1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
5 Contributed by Chris Smith (csmith@convex.com).
6 Heavily modified by Michael Meissner (meissner@cygnus.com),
7 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 /* Build tables of static constructors and destructors and run ld. */
32 #if ! defined( SIGCHLD ) && defined( SIGCLD )
33 # define SIGCHLD SIGCLD
36 #ifdef vfork /* Autoconf may define this to fork for us. */
37 # define VFORK_STRING "fork"
39 # define VFORK_STRING "vfork"
45 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
46 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
49 #ifndef LIBRARY_PATH_ENV
50 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
61 /* Obstack allocation and deallocation routines. */
62 #define obstack_chunk_alloc xmalloc
63 #define obstack_chunk_free free
65 /* On certain systems, we have code that works by scanning the object file
66 directly. But this code uses system-specific header files and library
67 functions, so turn it off in a cross-compiler. Likewise, the names of
68 the utilities are not correct for a cross-compiler; we have to hope that
69 cross-versions are in the proper directories. */
72 #undef SUNOS4_SHARED_LIBRARIES
73 #undef OBJECT_FORMAT_COFF
74 #undef OBJECT_FORMAT_ROSE
76 #undef REAL_LD_FILE_NAME
77 #undef REAL_NM_FILE_NAME
78 #undef REAL_STRIP_FILE_NAME
81 /* If we cannot use a special method, use the ordinary one:
82 run nm to find what symbols are present.
83 In a cross-compiler, this means you need a cross nm,
84 but that is not quite as unpleasant as special headers. */
86 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
87 #define OBJECT_FORMAT_NONE
90 #ifdef OBJECT_FORMAT_COFF
99 /* Many versions of ldfcn.h define these. */
107 /* Some systems have an ISCOFF macro, but others do not. In some cases
108 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
109 that either do not have an ISCOFF macro in /usr/include or for those
110 where it is wrong. */
113 #define MY_ISCOFF(X) ISCOFF (X)
116 #endif /* OBJECT_FORMAT_COFF */
118 #ifdef OBJECT_FORMAT_ROSE
125 #include <sys/mman.h>
129 #include <mach_o_format.h>
130 #include <mach_o_header.h>
131 #include <mach_o_vals.h>
132 #include <mach_o_types.h>
134 #endif /* OBJECT_FORMAT_ROSE */
136 #ifdef OBJECT_FORMAT_NONE
138 /* Default flags to pass to nm. */
140 #define NM_FLAGS "-n"
143 #endif /* OBJECT_FORMAT_NONE */
145 /* Some systems use __main in a way incompatible with its use in gcc, in these
146 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
147 give the same symbol without quotes for an alternative entry point. You
148 must define both, or neither. */
150 #define NAME__MAIN "__main"
151 #define SYMBOL__MAIN __main
154 /* This must match tree.h. */
155 #define DEFAULT_INIT_PRIORITY 65535
157 #ifndef COLLECT_SHARED_INIT_FUNC
158 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
159 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
161 #ifndef COLLECT_SHARED_FINI_FUNC
162 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
163 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
166 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
167 #define SCAN_LIBRARIES
171 int do_collecting
= 1;
173 int do_collecting
= 0;
176 /* Nonzero if we should suppress the automatic demangling of identifiers
177 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
180 /* Linked lists of constructor and destructor names. */
196 /* Enumeration giving which pass this is for scanning the program file. */
199 PASS_FIRST
, /* without constructors */
200 PASS_OBJ
, /* individual objects */
201 PASS_LIB
, /* looking for shared libraries */
202 PASS_SECOND
/* with constructors linked in */
205 int vflag
; /* true if -v */
206 static int rflag
; /* true if -r */
207 static int strip_flag
; /* true if -s */
208 #ifdef COLLECT_EXPORT_LIST
209 static int export_flag
; /* true if -bE */
210 static int aix64_flag
; /* true if -b64 */
213 int debug
; /* true if -debug */
215 static int shared_obj
; /* true if -shared */
217 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
218 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
219 #ifdef COLLECT_EXPORT_LIST
220 static const char *export_file
; /* <xxx>.x for AIX export list. */
222 const char *ldout
; /* File for ld errors. */
223 static const char *output_file
; /* Output file for ld. */
224 static const char *nm_file_name
; /* pathname of nm */
226 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
228 static const char *strip_file_name
; /* pathname of strip */
229 const char *c_file_name
; /* pathname of gcc */
230 static char *initname
, *fininame
; /* names of init and fini funcs */
232 static struct head constructors
; /* list of constructors found */
233 static struct head destructors
; /* list of destructors found */
234 #ifdef COLLECT_EXPORT_LIST
235 static struct head exports
; /* list of exported symbols */
237 static struct head frame_tables
; /* list of frame unwind info tables */
239 struct obstack temporary_obstack
;
240 struct obstack permanent_obstack
;
241 char * temporary_firstobj
;
243 /* Holds the return value of pexecute. */
246 /* Defined in the automatically-generated underscore.c. */
247 extern int prepends_underscore
;
249 #ifndef GET_ENV_PATH_LIST
250 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
253 /* Structure to hold all the directories in which to search for files to
258 const char *prefix
; /* String to prepend to the path. */
259 struct prefix_list
*next
; /* Next in linked list. */
264 struct prefix_list
*plist
; /* List of prefixes to try */
265 int max_len
; /* Max length of a prefix in PLIST */
266 const char *name
; /* Name of this list (used in config stuff) */
269 #ifdef COLLECT_EXPORT_LIST
270 /* Lists to keep libraries to be scanned for global constructors/destructors. */
271 static struct head libs
; /* list of libraries */
272 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
273 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
274 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
275 &libpath_lib_dirs
, NULL
};
276 static const char *const libexts
[3] = {"a", "so", NULL
}; /* possible library extensions */
279 static void handler
PARAMS ((int));
280 static int is_ctor_dtor
PARAMS ((const char *));
281 static char *find_a_file
PARAMS ((struct path_prefix
*, const char *));
282 static void add_prefix
PARAMS ((struct path_prefix
*, const char *));
283 static void prefix_from_env
PARAMS ((const char *, struct path_prefix
*));
284 static void prefix_from_string
PARAMS ((const char *, struct path_prefix
*));
285 static void do_wait
PARAMS ((const char *));
286 static void fork_execute
PARAMS ((const char *, char **));
287 static void maybe_unlink
PARAMS ((const char *));
288 static void add_to_list
PARAMS ((struct head
*, const char *));
289 static int extract_init_priority
PARAMS ((const char *));
290 static void sort_ids
PARAMS ((struct head
*));
291 static void write_list
PARAMS ((FILE *, const char *, struct id
*));
292 #ifdef COLLECT_EXPORT_LIST
293 static void dump_list
PARAMS ((FILE *, const char *, struct id
*));
296 static void dump_prefix_list
PARAMS ((FILE *, const char *, struct prefix_list
*));
298 static void write_list_with_asm
PARAMS ((FILE *, const char *, struct id
*));
299 static void write_c_file
PARAMS ((FILE *, const char *));
300 static void write_c_file_stat
PARAMS ((FILE *, const char *));
301 #ifndef LD_INIT_SWITCH
302 static void write_c_file_glob
PARAMS ((FILE *, const char *));
304 static void scan_prog_file
PARAMS ((const char *, enum pass
));
305 #ifdef SCAN_LIBRARIES
306 static void scan_libraries
PARAMS ((const char *));
308 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
309 static int is_in_args
PARAMS ((const char *, const char **, const char **));
311 #ifdef COLLECT_EXPORT_LIST
313 static int is_in_list
PARAMS ((const char *, struct id
*));
315 static void write_aix_file
PARAMS ((FILE *, struct id
*));
316 static char *resolve_lib_name
PARAMS ((const char *));
317 static int ignore_library
PARAMS ((const char *));
319 static char *extract_string
PARAMS ((const char **));
322 static int dup2
PARAMS ((int, int));
335 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
338 close (fdtmp
[--fdx
]);
342 #endif /* ! HAVE_DUP2 */
344 /* Delete tempfiles and exit function. */
347 collect_exit (status
)
350 if (c_file
!= 0 && c_file
[0])
351 maybe_unlink (c_file
);
353 if (o_file
!= 0 && o_file
[0])
354 maybe_unlink (o_file
);
356 #ifdef COLLECT_EXPORT_LIST
357 if (export_file
!= 0 && export_file
[0])
358 maybe_unlink (export_file
);
361 if (ldout
!= 0 && ldout
[0])
364 maybe_unlink (ldout
);
367 if (status
!= 0 && output_file
!= 0 && output_file
[0])
368 maybe_unlink (output_file
);
374 /* Notify user of a non-error. */
376 notice
VPARAMS ((const char *msgid
, ...))
379 VA_FIXEDARG (ap
, const char *, msgid
);
381 vfprintf (stderr
, _(msgid
), ap
);
385 /* Die when sys call fails. */
388 fatal_perror
VPARAMS ((const char * msgid
, ...))
393 VA_FIXEDARG (ap
, const char *, msgid
);
395 fprintf (stderr
, "collect2: ");
396 vfprintf (stderr
, _(msgid
), ap
);
397 fprintf (stderr
, ": %s\n", xstrerror (e
));
400 collect_exit (FATAL_EXIT_CODE
);
406 fatal
VPARAMS ((const char * msgid
, ...))
409 VA_FIXEDARG (ap
, const char *, msgid
);
411 fprintf (stderr
, "collect2: ");
412 vfprintf (stderr
, _(msgid
), ap
);
413 fprintf (stderr
, "\n");
416 collect_exit (FATAL_EXIT_CODE
);
419 /* Write error message. */
422 error
VPARAMS ((const char * msgid
, ...))
425 VA_FIXEDARG (ap
, const char *, msgid
);
427 fprintf (stderr
, "collect2: ");
428 vfprintf (stderr
, _(msgid
), ap
);
429 fprintf (stderr
, "\n");
433 /* In case obstack is linked in, and abort is defined to fancy_abort,
434 provide a default entry. */
439 fatal ("internal error");
446 if (c_file
!= 0 && c_file
[0])
447 maybe_unlink (c_file
);
449 if (o_file
!= 0 && o_file
[0])
450 maybe_unlink (o_file
);
452 if (ldout
!= 0 && ldout
[0])
453 maybe_unlink (ldout
);
455 #ifdef COLLECT_EXPORT_LIST
456 if (export_file
!= 0 && export_file
[0])
457 maybe_unlink (export_file
);
460 signal (signo
, SIG_DFL
);
461 kill (getpid (), signo
);
469 return access (name
, R_OK
) == 0;
472 /* Parse a reasonable subset of shell quoting syntax. */
489 obstack_1grow (&temporary_obstack
, c
);
490 else if (! inside
&& c
== ' ')
492 else if (! inside
&& c
== '\\')
497 obstack_1grow (&temporary_obstack
, c
);
500 obstack_1grow (&temporary_obstack
, '\0');
502 return obstack_finish (&temporary_obstack
);
509 FILE *stream
= fopen (name
, "r");
516 while (c
= getc (stream
),
517 c
!= EOF
&& (ISIDNUM (c
) || c
== '$' || c
== '.'))
518 obstack_1grow (&temporary_obstack
, c
);
519 if (obstack_object_size (&temporary_obstack
) > 0)
521 const char *word
, *p
;
523 obstack_1grow (&temporary_obstack
, '\0');
524 word
= obstack_finish (&temporary_obstack
);
527 ++word
, putc ('.', stderr
);
529 if (*p
== '_' && prepends_underscore
)
535 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
| DMGL_VERBOSE
);
540 fputs (result
, stderr
);
542 diff
= strlen (word
) - strlen (result
);
543 while (diff
> 0 && c
== ' ')
544 --diff
, putc (' ', stderr
);
545 while (diff
< 0 && c
== ' ')
546 ++diff
, c
= getc (stream
);
551 fputs (word
, stderr
);
554 obstack_free (&temporary_obstack
, temporary_firstobj
);
563 /* Decide whether the given symbol is: a constructor (1), a destructor
564 (2), a routine in a shared object that calls all the constructors
565 (3) or destructors (4), a DWARF exception-handling table (5), or
566 nothing special (0). */
572 struct names
{ const char *const name
; const int len
; const int ret
;
573 const int two_underscores
; };
575 const struct names
*p
;
577 const char *orig_s
= s
;
579 static const struct names special
[] = {
580 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
581 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
582 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
583 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
584 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
585 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
586 cfront has its own linker procedure to collect them;
587 if collect2 gets them too, they get collected twice
588 when the cfront procedure is run and the compiler used
589 for linking happens to be GCC. */
590 { "sti__", sizeof ("sti__")-1, 1, 1 },
591 { "std__", sizeof ("std__")-1, 2, 1 },
592 #endif /* CFRONT_LOSSAGE */
596 while ((ch
= *s
) == '_')
602 for (p
= &special
[0]; p
->len
> 0; p
++)
605 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
606 && strncmp(s
, p
->name
, p
->len
) == 0)
614 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
615 and one from the PATH variable. */
617 static struct path_prefix cpath
, path
;
620 /* This is the name of the target machine. We use it to form the name
621 of the files to execute. */
623 static const char *const target_machine
= TARGET_MACHINE
;
626 /* Search for NAME using prefix list PPREFIX. We only look for executable
629 Return 0 if not found, otherwise return its name, allocated with malloc. */
632 find_a_file (pprefix
, name
)
633 struct path_prefix
*pprefix
;
637 struct prefix_list
*pl
;
638 int len
= pprefix
->max_len
+ strlen (name
) + 1;
641 fprintf (stderr
, "Looking for '%s'\n", name
);
643 #ifdef HOST_EXECUTABLE_SUFFIX
644 len
+= strlen (HOST_EXECUTABLE_SUFFIX
);
647 temp
= xmalloc (len
);
649 /* Determine the filename to execute (special case for absolute paths). */
652 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
653 || (*name
&& name
[1] == ':')
657 if (access (name
, X_OK
) == 0)
662 fprintf (stderr
, " - found: absolute path\n");
667 #ifdef HOST_EXECUTABLE_SUFFIX
668 /* Some systems have a suffix for executable files.
669 So try appending that. */
671 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
673 if (access (temp
, X_OK
) == 0)
678 fprintf (stderr
, " - failed to locate using absolute path\n");
681 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
685 strcpy (temp
, pl
->prefix
);
688 if (stat (temp
, &st
) >= 0
689 && ! S_ISDIR (st
.st_mode
)
690 && access (temp
, X_OK
) == 0)
693 #ifdef HOST_EXECUTABLE_SUFFIX
694 /* Some systems have a suffix for executable files.
695 So try appending that. */
696 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
698 if (stat (temp
, &st
) >= 0
699 && ! S_ISDIR (st
.st_mode
)
700 && access (temp
, X_OK
) == 0)
705 if (debug
&& pprefix
->plist
== NULL
)
706 fprintf (stderr
, " - failed: no entries in prefix list\n");
712 /* Add an entry for PREFIX to prefix list PPREFIX. */
715 add_prefix (pprefix
, prefix
)
716 struct path_prefix
*pprefix
;
719 struct prefix_list
*pl
, **prev
;
724 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
729 prev
= &pprefix
->plist
;
731 /* Keep track of the longest prefix */
733 len
= strlen (prefix
);
734 if (len
> pprefix
->max_len
)
735 pprefix
->max_len
= len
;
737 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
738 pl
->prefix
= xstrdup (prefix
);
743 pl
->next
= (struct prefix_list
*) 0;
747 /* Take the value of the environment variable ENV, break it into a path, and
748 add of the entries to PPREFIX. */
751 prefix_from_env (env
, pprefix
)
753 struct path_prefix
*pprefix
;
756 GET_ENV_PATH_LIST (p
, env
);
759 prefix_from_string (p
, pprefix
);
763 prefix_from_string (p
, pprefix
)
765 struct path_prefix
*pprefix
;
767 const char *startp
, *endp
;
768 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
771 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
776 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
778 strncpy (nstore
, startp
, endp
-startp
);
781 strcpy (nstore
, "./");
783 else if (! IS_DIR_SEPARATOR (endp
[-1]))
785 nstore
[endp
-startp
] = DIR_SEPARATOR
;
786 nstore
[endp
-startp
+1] = 0;
789 nstore
[endp
-startp
] = 0;
792 fprintf (stderr
, " - add prefix: %s\n", nstore
);
794 add_prefix (pprefix
, nstore
);
797 endp
= startp
= endp
+ 1;
806 int main
PARAMS ((int, char *[]));
812 static const char *const ld_suffix
= "ld";
813 static const char *const real_ld_suffix
= "real-ld";
814 static const char *const collect_ld_suffix
= "collect-ld";
815 static const char *const nm_suffix
= "nm";
816 static const char *const gnm_suffix
= "gnm";
818 static const char *const ldd_suffix
= LDD_SUFFIX
;
820 static const char *const strip_suffix
= "strip";
821 static const char *const gstrip_suffix
= "gstrip";
824 /* If we look for a program in the compiler directories, we just use
825 the short name, since these directories are already system-specific.
826 But it we look for a program in the system directories, we need to
827 qualify the program name with the target machine. */
829 const char *const full_ld_suffix
=
830 concat(target_machine
, "-", ld_suffix
, NULL
);
831 const char *const full_nm_suffix
=
832 concat (target_machine
, "-", nm_suffix
, NULL
);
833 const char *const full_gnm_suffix
=
834 concat (target_machine
, "-", gnm_suffix
, NULL
);
836 const char *const full_ldd_suffix
=
837 concat (target_machine
, "-", ldd_suffix
, NULL
);
839 const char *const full_strip_suffix
=
840 concat (target_machine
, "-", strip_suffix
, NULL
);
841 const char *const full_gstrip_suffix
=
842 concat (target_machine
, "-", gstrip_suffix
, NULL
);
844 const char *const full_ld_suffix
= ld_suffix
;
845 const char *const full_nm_suffix
= nm_suffix
;
846 const char *const full_gnm_suffix
= gnm_suffix
;
848 const char *const full_ldd_suffix
= ldd_suffix
;
850 const char *const full_strip_suffix
= strip_suffix
;
851 const char *const full_gstrip_suffix
= gstrip_suffix
;
852 #endif /* CROSS_COMPILE */
856 #ifdef COLLECT_EXPORT_LIST
859 const char *ld_file_name
;
870 int num_c_args
= argc
+9;
872 no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
874 /* Suppress demangling by the real linker, which may be broken. */
875 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
877 #if defined (COLLECT2_HOST_INITIALIZATION)
878 /* Perform system dependent initialization, if necessary. */
879 COLLECT2_HOST_INITIALIZATION
;
883 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
884 receive the signal. A different setting is inheritable */
885 signal (SIGCHLD
, SIG_DFL
);
890 /* Do not invoke xcalloc before this point, since locale needs to be
891 set first, in case a diagnostic is issued. */
893 ld1
= (const char **)(ld1_argv
= (char **) xcalloc(sizeof (char *), argc
+3));
894 ld2
= (const char **)(ld2_argv
= (char **) xcalloc(sizeof (char *), argc
+10));
895 object
= (const char **)(object_lst
= (char **) xcalloc(sizeof (char *), argc
));
901 /* Parse command line early for instances of -debug. This allows
902 the debug flag to be set before functions like find_a_file()
907 for (i
= 1; argv
[i
] != NULL
; i
++)
908 if (! strcmp (argv
[i
], "-debug"))
913 #ifndef DEFAULT_A_OUT_NAME
914 output_file
= "a.out";
916 output_file
= DEFAULT_A_OUT_NAME
;
919 obstack_begin (&temporary_obstack
, 0);
920 obstack_begin (&permanent_obstack
, 0);
921 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
923 current_demangling_style
= auto_demangling
;
924 p
= getenv ("COLLECT_GCC_OPTIONS");
927 const char *q
= extract_string (&p
);
928 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
931 obstack_free (&temporary_obstack
, temporary_firstobj
);
933 /* -fno-exceptions -w */
936 c_ptr
= (const char **)
937 (c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
));
940 fatal ("no arguments");
943 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
944 signal (SIGQUIT
, handler
);
946 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
947 signal (SIGINT
, handler
);
949 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
950 signal (SIGALRM
, handler
);
953 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
954 signal (SIGHUP
, handler
);
956 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
957 signal (SIGSEGV
, handler
);
959 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
960 signal (SIGBUS
, handler
);
963 /* Extract COMPILER_PATH and PATH into our prefix list. */
964 prefix_from_env ("COMPILER_PATH", &cpath
);
965 prefix_from_env ("PATH", &path
);
967 /* Try to discover a valid linker/nm/strip to use. */
969 /* Maybe we know the right file to use (if not cross). */
971 #ifdef DEFAULT_LINKER
972 if (access (DEFAULT_LINKER
, X_OK
) == 0)
973 ld_file_name
= DEFAULT_LINKER
;
974 if (ld_file_name
== 0)
976 #ifdef REAL_LD_FILE_NAME
977 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
978 if (ld_file_name
== 0)
980 /* Search the (target-specific) compiler dirs for ld'. */
981 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
982 /* Likewise for `collect-ld'. */
983 if (ld_file_name
== 0)
984 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
985 /* Search the compiler directories for `ld'. We have protection against
986 recursive calls in find_a_file. */
987 if (ld_file_name
== 0)
988 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
989 /* Search the ordinary system bin directories
990 for `ld' (if native linking) or `TARGET-ld' (if cross). */
991 if (ld_file_name
== 0)
992 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
994 #ifdef REAL_NM_FILE_NAME
995 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
996 if (nm_file_name
== 0)
998 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
999 if (nm_file_name
== 0)
1000 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
1001 if (nm_file_name
== 0)
1002 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
1003 if (nm_file_name
== 0)
1004 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
1007 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
1008 if (ldd_file_name
== 0)
1009 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
1012 #ifdef REAL_STRIP_FILE_NAME
1013 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1014 if (strip_file_name
== 0)
1016 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1017 if (strip_file_name
== 0)
1018 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1019 if (strip_file_name
== 0)
1020 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1021 if (strip_file_name
== 0)
1022 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1024 /* Determine the full path name of the C compiler to use. */
1025 c_file_name
= getenv ("COLLECT_GCC");
1026 if (c_file_name
== 0)
1028 #ifdef CROSS_COMPILE
1029 c_file_name
= concat (target_machine
, "-gcc", NULL
);
1031 c_file_name
= "gcc";
1035 p
= find_a_file (&cpath
, c_file_name
);
1037 /* Here it should be safe to use the system search path since we should have
1038 already qualified the name of the compiler when it is needed. */
1040 p
= find_a_file (&path
, c_file_name
);
1045 *ld1
++ = *ld2
++ = ld_file_name
;
1047 /* Make temp file names. */
1048 c_file
= make_temp_file (".c");
1049 o_file
= make_temp_file (".o");
1050 #ifdef COLLECT_EXPORT_LIST
1051 export_file
= make_temp_file (".x");
1053 ldout
= make_temp_file (".ld");
1054 *c_ptr
++ = c_file_name
;
1061 #ifdef COLLECT_EXPORT_LIST
1062 /* Generate a list of directories from LIBPATH. */
1063 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1064 /* Add to this list also two standard directories where
1065 AIX loader always searches for libraries. */
1066 add_prefix (&libpath_lib_dirs
, "/lib");
1067 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1070 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1072 AIX support needs to know if -shared has been specified before
1073 parsing commandline arguments. */
1075 p
= getenv ("COLLECT_GCC_OPTIONS");
1078 const char *q
= extract_string (&p
);
1079 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1080 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1081 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1082 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1083 if (strcmp (q
, "-shared") == 0)
1085 if (*q
== '-' && q
[1] == 'B')
1087 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1090 q
= extract_string (&p
);
1091 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1095 obstack_free (&temporary_obstack
, temporary_firstobj
);
1096 *c_ptr
++ = "-fno-exceptions";
1099 /* !!! When GCC calls collect2,
1100 it does not know whether it is calling collect2 or ld.
1101 So collect2 cannot meaningfully understand any options
1102 except those ld understands.
1103 If you propose to make GCC pass some other option,
1104 just imagine what will happen if ld is really ld!!! */
1106 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1107 /* After the first file, put in the c++ rt0. */
1110 while ((arg
= *++argv
) != (char *) 0)
1112 *ld1
++ = *ld2
++ = arg
;
1118 #ifdef COLLECT_EXPORT_LIST
1119 /* We want to disable automatic exports on AIX when user
1120 explicitly puts an export list in command line */
1122 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1124 else if (arg
[2] == '6' && arg
[3] == '4')
1130 if (!strcmp (arg
, "-debug"))
1132 /* Already parsed. */
1141 /* place o_file BEFORE this argument! */
1147 #ifdef COLLECT_EXPORT_LIST
1149 /* Resolving full library name. */
1150 const char *s
= resolve_lib_name (arg
+2);
1152 /* Saving a full library name. */
1153 add_to_list (&libs
, s
);
1158 #ifdef COLLECT_EXPORT_LIST
1159 /* Saving directories where to search for libraries. */
1161 add_prefix (&cmdline_lib_dirs
, arg
+2);
1164 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1166 if (is_in_args (arg
, (const char **) ld1_argv
, ld1
-1))
1169 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1174 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1176 #ifdef SWITCHES_NEED_SPACES
1177 && ! strchr (SWITCHES_NEED_SPACES
, arg
[1])
1181 output_file
= &arg
[2];
1190 if (arg
[2] == '\0' && do_collecting
)
1192 /* We must strip after the nm run, otherwise C++ linking
1193 will not work. Thus we strip in the second ld run, or
1194 else with strip if there is no second ld run. */
1206 else if ((p
= strrchr (arg
, '.')) != (char *) 0
1207 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1208 || strcmp (p
, ".so") == 0 || strcmp (p
, ".lo") == 0
1209 || strcmp (p
, ".obj") == 0))
1218 /* place o_file BEFORE this argument! */
1224 if (p
[1] == 'o' || p
[1] == 'l')
1226 #ifdef COLLECT_EXPORT_LIST
1227 /* libraries can be specified directly, i.e. without -l flag. */
1230 /* Saving a full library name. */
1231 add_to_list (&libs
, arg
);
1237 #ifdef COLLECT_EXPORT_LIST
1238 /* This is added only for debugging purposes. */
1241 fprintf (stderr
, "List of libraries:\n");
1242 dump_list (stderr
, "\t", libs
.first
);
1245 /* The AIX linker will discard static constructors in object files if
1246 nothing else in the file is referenced, so look at them first. */
1248 const char **export_object_lst
= (const char **)object_lst
;
1250 while (export_object_lst
< object
)
1251 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1254 struct id
*list
= libs
.first
;
1256 for (; list
; list
= list
->next
)
1257 scan_prog_file (list
->name
, PASS_FIRST
);
1262 char *buf
= concat ("-bE:", export_file
, NULL
);
1267 exportf
= fopen (export_file
, "w");
1268 if (exportf
== (FILE *) 0)
1269 fatal_perror ("fopen %s", export_file
);
1270 write_aix_file (exportf
, exports
.first
);
1271 if (fclose (exportf
))
1272 fatal_perror ("fclose %s", export_file
);
1277 *c_ptr
= *ld1
= *object
= (char *) 0;
1281 notice ("collect2 version %s", version_string
);
1282 #ifdef TARGET_VERSION
1285 fprintf (stderr
, "\n");
1291 fprintf (stderr
, "ld_file_name = %s\n",
1292 (ld_file_name
? ld_file_name
: "not found"));
1293 fprintf (stderr
, "c_file_name = %s\n",
1294 (c_file_name
? c_file_name
: "not found"));
1295 fprintf (stderr
, "nm_file_name = %s\n",
1296 (nm_file_name
? nm_file_name
: "not found"));
1298 fprintf (stderr
, "ldd_file_name = %s\n",
1299 (ldd_file_name
? ldd_file_name
: "not found"));
1301 fprintf (stderr
, "strip_file_name = %s\n",
1302 (strip_file_name
? strip_file_name
: "not found"));
1303 fprintf (stderr
, "c_file = %s\n",
1304 (c_file
? c_file
: "not found"));
1305 fprintf (stderr
, "o_file = %s\n",
1306 (o_file
? o_file
: "not found"));
1308 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1310 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1312 ptr
= getenv ("COLLECT_GCC");
1314 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1316 ptr
= getenv ("COMPILER_PATH");
1318 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1320 ptr
= getenv (LIBRARY_PATH_ENV
);
1322 fprintf (stderr
, "%-20s= %s\n", LIBRARY_PATH_ENV
, ptr
);
1324 fprintf (stderr
, "\n");
1327 /* Load the program, searching all libraries and attempting to provide
1328 undefined symbols from repository information. */
1330 /* On AIX we do this later. */
1331 #ifndef COLLECT_EXPORT_LIST
1332 do_tlink (ld1_argv
, object_lst
);
1335 /* If -r or they will be run via some other method, do not build the
1336 constructor or destructor list, just return now. */
1338 #ifndef COLLECT_EXPORT_LIST
1343 #ifdef COLLECT_EXPORT_LIST
1344 /* Do the link we avoided above if we are exiting. */
1345 do_tlink (ld1_argv
, object_lst
);
1347 /* But make sure we delete the export file we may have created. */
1348 if (export_file
!= 0 && export_file
[0])
1349 maybe_unlink (export_file
);
1351 maybe_unlink (c_file
);
1352 maybe_unlink (o_file
);
1356 /* Examine the namelist with nm and search it for static constructors
1357 and destructors to call.
1358 Write the constructor and destructor tables to a .s file and reload. */
1360 /* On AIX we already scanned for global constructors/destructors. */
1361 #ifndef COLLECT_EXPORT_LIST
1362 scan_prog_file (output_file
, PASS_FIRST
);
1365 #ifdef SCAN_LIBRARIES
1366 scan_libraries (output_file
);
1371 notice ("%d constructor(s) found\n", constructors
.number
);
1372 notice ("%d destructor(s) found\n", destructors
.number
);
1373 notice ("%d frame table(s) found\n", frame_tables
.number
);
1376 if (constructors
.number
== 0 && destructors
.number
== 0
1377 && frame_tables
.number
== 0
1378 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1379 /* If we will be running these functions ourselves, we want to emit
1380 stubs into the shared library so that we do not have to relink
1381 dependent programs when we add static objects. */
1386 #ifdef COLLECT_EXPORT_LIST
1387 /* Do tlink without additional code generation */
1388 do_tlink (ld1_argv
, object_lst
);
1390 /* Strip now if it was requested on the command line. */
1393 char **real_strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1394 const char ** strip_argv
= (const char **) real_strip_argv
;
1396 strip_argv
[0] = strip_file_name
;
1397 strip_argv
[1] = output_file
;
1398 strip_argv
[2] = (char *) 0;
1399 fork_execute ("strip", real_strip_argv
);
1402 #ifdef COLLECT_EXPORT_LIST
1403 maybe_unlink (export_file
);
1405 maybe_unlink (c_file
);
1406 maybe_unlink (o_file
);
1410 /* Sort ctor and dtor lists by priority. */
1411 sort_ids (&constructors
);
1412 sort_ids (&destructors
);
1414 maybe_unlink(output_file
);
1415 outf
= fopen (c_file
, "w");
1416 if (outf
== (FILE *) 0)
1417 fatal_perror ("fopen %s", c_file
);
1419 write_c_file (outf
, c_file
);
1422 fatal_perror ("fclose %s", c_file
);
1424 /* Tell the linker that we have initializer and finalizer functions. */
1425 #ifdef LD_INIT_SWITCH
1426 #ifdef COLLECT_EXPORT_LIST
1427 *ld2
++ = concat (LD_INIT_SWITCH
, ":", initname
, ":", fininame
, NULL
);
1429 *ld2
++ = LD_INIT_SWITCH
;
1431 *ld2
++ = LD_FINI_SWITCH
;
1436 #ifdef COLLECT_EXPORT_LIST
1439 /* If we did not add export flag to link arguments before, add it to
1440 second link phase now. No new exports should have been added. */
1441 if (! exports
.first
)
1442 *ld2
++ = concat ("-bE:", export_file
, NULL
);
1444 add_to_list (&exports
, initname
);
1445 add_to_list (&exports
, fininame
);
1446 add_to_list (&exports
, "_GLOBAL__DI");
1447 add_to_list (&exports
, "_GLOBAL__DD");
1448 exportf
= fopen (export_file
, "w");
1449 if (exportf
== (FILE *) 0)
1450 fatal_perror ("fopen %s", export_file
);
1451 write_aix_file (exportf
, exports
.first
);
1452 if (fclose (exportf
))
1453 fatal_perror ("fclose %s", export_file
);
1457 /* End of arguments to second link phase. */
1462 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1463 output_file
, c_file
);
1464 write_c_file (stderr
, "stderr");
1465 fprintf (stderr
, "========== end of c_file\n\n");
1466 #ifdef COLLECT_EXPORT_LIST
1467 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1468 write_aix_file (stderr
, exports
.first
);
1469 fprintf (stderr
, "========== end of export_file\n\n");
1473 /* Assemble the constructor and destructor tables.
1474 Link the tables in with the rest of the program. */
1476 fork_execute ("gcc", c_argv
);
1477 #ifdef COLLECT_EXPORT_LIST
1478 /* On AIX we must call tlink because of possible templates resolution */
1479 do_tlink (ld2_argv
, object_lst
);
1481 /* Otherwise, simply call ld because tlink is already done */
1482 fork_execute ("ld", ld2_argv
);
1484 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1485 constructors/destructors in shared libraries. */
1486 scan_prog_file (output_file
, PASS_SECOND
);
1489 maybe_unlink (c_file
);
1490 maybe_unlink (o_file
);
1492 #ifdef COLLECT_EXPORT_LIST
1493 maybe_unlink (export_file
);
1500 /* Wait for a process to finish, and exit if a non-zero status is found. */
1508 pwait (pexecute_pid
, &status
, 0);
1511 if (WIFSIGNALED (status
))
1513 int sig
= WTERMSIG (status
);
1514 error ("%s terminated with signal %d [%s]%s",
1515 prog
, sig
, strsignal(sig
),
1516 status
& 0200 ? "" : ", core dumped");
1517 collect_exit (FATAL_EXIT_CODE
);
1520 if (WIFEXITED (status
))
1521 return WEXITSTATUS (status
);
1530 int ret
= collect_wait (prog
);
1533 error ("%s returned %d exit status", prog
, ret
);
1539 /* Execute a program, and wait for the reply. */
1542 collect_execute (prog
, argv
, redir
)
1549 int redir_handle
= -1;
1550 int stdout_save
= -1;
1551 int stderr_save
= -1;
1559 fprintf (stderr
, "%s", argv
[0]);
1561 notice ("[cannot find %s]", prog
);
1563 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1564 fprintf (stderr
, " %s", str
);
1566 fprintf (stderr
, "\n");
1572 /* If we cannot find a program we need, complain error. Do this here
1573 since we might not end up needing something that we could not find. */
1576 fatal ("cannot find `%s'", prog
);
1580 /* Open response file. */
1581 redir_handle
= open (redir
, O_WRONLY
| O_TRUNC
| O_CREAT
);
1583 /* Duplicate the stdout and stderr file handles
1584 so they can be restored later. */
1585 stdout_save
= dup (STDOUT_FILENO
);
1586 if (stdout_save
== -1)
1587 fatal_perror ("redirecting stdout: %s", redir
);
1588 stderr_save
= dup (STDERR_FILENO
);
1589 if (stderr_save
== -1)
1590 fatal_perror ("redirecting stdout: %s", redir
);
1592 /* Redirect stdout & stderr to our response file. */
1593 dup2 (redir_handle
, STDOUT_FILENO
);
1594 dup2 (redir_handle
, STDERR_FILENO
);
1597 pexecute_pid
= pexecute (argv
[0], argv
, argv
[0], NULL
,
1598 &errmsg_fmt
, &errmsg_arg
,
1599 (PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
));
1603 /* Restore stdout and stderr to their previous settings. */
1604 dup2 (stdout_save
, STDOUT_FILENO
);
1605 dup2 (stderr_save
, STDERR_FILENO
);
1607 /* Close response file. */
1608 close (redir_handle
);
1611 if (pexecute_pid
== -1)
1612 fatal_perror (errmsg_fmt
, errmsg_arg
);
1616 fork_execute (prog
, argv
)
1620 collect_execute (prog
, argv
, NULL
);
1624 /* Unlink a file unless we are debugging. */
1633 notice ("[Leaving %s]\n", file
);
1637 static long sequence_number
= 0;
1639 /* Add a name to a linked list. */
1642 add_to_list (head_ptr
, name
)
1643 struct head
*head_ptr
;
1647 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1649 strcpy (newid
->name
, name
);
1651 if (head_ptr
->first
)
1652 head_ptr
->last
->next
= newid
;
1654 head_ptr
->first
= newid
;
1656 /* Check for duplicate symbols. */
1657 for (p
= head_ptr
->first
;
1658 strcmp (name
, p
->name
) != 0;
1663 head_ptr
->last
->next
= 0;
1668 newid
->sequence
= ++sequence_number
;
1669 head_ptr
->last
= newid
;
1673 /* Grab the init priority number from an init function name that
1674 looks like "_GLOBAL_.I.12345.foo". */
1677 extract_init_priority (name
)
1682 while (name
[pos
] == '_')
1684 pos
+= 10; /* strlen ("GLOBAL__X_") */
1686 /* Extract init_p number from ctor/dtor name. */
1687 pri
= atoi (name
+ pos
);
1688 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1691 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1692 ctors will be run from right to left, dtors from left to right. */
1696 struct head
*head_ptr
;
1698 /* id holds the current element to insert. id_next holds the next
1699 element to insert. id_ptr iterates through the already sorted elements
1700 looking for the place to insert id. */
1701 struct id
*id
, *id_next
, **id_ptr
;
1703 id
= head_ptr
->first
;
1705 /* We don't have any sorted elements yet. */
1706 head_ptr
->first
= NULL
;
1708 for (; id
; id
= id_next
)
1711 id
->sequence
= extract_init_priority (id
->name
);
1713 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1715 /* If the sequence numbers are the same, we put the id from the
1716 file later on the command line later in the list. */
1717 || id
->sequence
> (*id_ptr
)->sequence
1718 /* Hack: do lexical compare, too.
1719 || (id->sequence == (*id_ptr)->sequence
1720 && strcmp (id->name, (*id_ptr)->name) > 0) */
1729 /* Now set the sequence numbers properly so write_c_file works. */
1730 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1731 id
->sequence
= ++sequence_number
;
1734 /* Write: `prefix', the names on list LIST, `suffix'. */
1737 write_list (stream
, prefix
, list
)
1744 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1749 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1750 /* Given a STRING, return nonzero if it occurs in the list in range
1751 [ARGS_BEGIN,ARGS_END). */
1754 is_in_args (string
, args_begin
, args_end
)
1756 const char **args_begin
;
1757 const char **args_end
;
1759 const char **args_pointer
;
1760 for (args_pointer
= args_begin
; args_pointer
!= args_end
; ++args_pointer
)
1761 if (strcmp (string
, *args_pointer
) == 0)
1765 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1767 #ifdef COLLECT_EXPORT_LIST
1768 /* This function is really used only on AIX, but may be useful. */
1771 is_in_list (prefix
, list
)
1777 if (!strcmp (prefix
, list
->name
)) return 1;
1783 #endif /* COLLECT_EXPORT_LIST */
1785 /* Added for debugging purpose. */
1786 #ifdef COLLECT_EXPORT_LIST
1788 dump_list (stream
, prefix
, list
)
1795 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1803 dump_prefix_list (stream
, prefix
, list
)
1806 struct prefix_list
*list
;
1810 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1817 write_list_with_asm (stream
, prefix
, list
)
1824 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1825 prefix
, list
->sequence
, list
->name
);
1830 /* Write out the constructor and destructor tables statically (for a shared
1831 object), along with the functions to execute them. */
1834 write_c_file_stat (stream
, name
)
1836 const char *name ATTRIBUTE_UNUSED
;
1840 int frames
= (frame_tables
.number
> 0);
1842 /* Figure out name of output_file, stripping off .so version. */
1843 p
= strrchr (output_file
, '/');
1859 if (strncmp (q
, ".so", 3) == 0)
1868 /* q points to null at end of the string (or . of the .so version) */
1869 prefix
= xmalloc (q
- p
+ 1);
1870 strncpy (prefix
, p
, q
- p
);
1872 for (r
= prefix
; *r
; r
++)
1873 if (!ISALNUM ((unsigned char)*r
))
1876 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1877 output_file
, prefix
);
1879 initname
= concat ("_GLOBAL__FI_", prefix
, NULL
);
1880 fininame
= concat ("_GLOBAL__FD_", prefix
, NULL
);
1884 /* Write the tables as C code */
1886 fprintf (stream
, "static int count;\n");
1887 fprintf (stream
, "typedef void entry_pt();\n");
1888 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1892 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1894 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1895 write_list (stream
, "\t\t&", frame_tables
.first
);
1896 fprintf (stream
, "\t0\n};\n");
1898 /* This must match what's in frame.h. */
1899 fprintf (stream
, "struct object {\n");
1900 fprintf (stream
, " void *pc_begin;\n");
1901 fprintf (stream
, " void *pc_end;\n");
1902 fprintf (stream
, " void *fde_begin;\n");
1903 fprintf (stream
, " void *fde_array;\n");
1904 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1905 fprintf (stream
, " struct object *next;\n");
1906 fprintf (stream
, "};\n");
1908 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1909 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1911 fprintf (stream
, "static void reg_frame () {\n");
1912 fprintf (stream
, "\tstatic struct object ob;\n");
1913 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1914 fprintf (stream
, "\t}\n");
1916 fprintf (stream
, "static void dereg_frame () {\n");
1917 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1918 fprintf (stream
, "\t}\n");
1921 fprintf (stream
, "void %s() {\n", initname
);
1922 if (constructors
.number
> 0 || frames
)
1924 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1925 write_list (stream
, "\t\t", constructors
.first
);
1927 fprintf (stream
, "\treg_frame,\n");
1928 fprintf (stream
, "\t};\n");
1929 fprintf (stream
, "\tentry_pt **p;\n");
1930 fprintf (stream
, "\tif (count++ != 0) return;\n");
1931 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1932 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1935 fprintf (stream
, "\t++count;\n");
1936 fprintf (stream
, "}\n");
1937 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1938 fprintf (stream
, "void %s() {\n", fininame
);
1939 if (destructors
.number
> 0 || frames
)
1941 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1942 write_list (stream
, "\t\t", destructors
.first
);
1944 fprintf (stream
, "\tdereg_frame,\n");
1945 fprintf (stream
, "\t};\n");
1946 fprintf (stream
, "\tentry_pt **p;\n");
1947 fprintf (stream
, "\tif (--count != 0) return;\n");
1948 fprintf (stream
, "\tp = dtors;\n");
1949 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
1950 destructors
.number
+ frames
);
1952 fprintf (stream
, "}\n");
1956 COLLECT_SHARED_INIT_FUNC(stream
, initname
);
1957 COLLECT_SHARED_FINI_FUNC(stream
, fininame
);
1961 /* Write the constructor/destructor tables. */
1963 #ifndef LD_INIT_SWITCH
1965 write_c_file_glob (stream
, name
)
1967 const char *name ATTRIBUTE_UNUSED
;
1969 /* Write the tables as C code */
1971 int frames
= (frame_tables
.number
> 0);
1973 fprintf (stream
, "typedef void entry_pt();\n\n");
1975 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1979 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1981 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1982 write_list (stream
, "\t\t&", frame_tables
.first
);
1983 fprintf (stream
, "\t0\n};\n");
1985 /* This must match what's in frame.h. */
1986 fprintf (stream
, "struct object {\n");
1987 fprintf (stream
, " void *pc_begin;\n");
1988 fprintf (stream
, " void *pc_end;\n");
1989 fprintf (stream
, " void *fde_begin;\n");
1990 fprintf (stream
, " void *fde_array;\n");
1991 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1992 fprintf (stream
, " struct object *next;\n");
1993 fprintf (stream
, "};\n");
1995 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1996 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1998 fprintf (stream
, "static void reg_frame () {\n");
1999 fprintf (stream
, "\tstatic struct object ob;\n");
2000 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2001 fprintf (stream
, "\t}\n");
2003 fprintf (stream
, "static void dereg_frame () {\n");
2004 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2005 fprintf (stream
, "\t}\n");
2008 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2009 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2010 write_list (stream
, "\t", constructors
.first
);
2012 fprintf (stream
, "\treg_frame,\n");
2013 fprintf (stream
, "\t0\n};\n\n");
2015 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2017 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2018 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2019 write_list (stream
, "\t", destructors
.first
);
2021 fprintf (stream
, "\tdereg_frame,\n");
2022 fprintf (stream
, "\t0\n};\n\n");
2024 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2025 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2027 #endif /* ! LD_INIT_SWITCH */
2030 write_c_file (stream
, name
)
2034 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2035 #ifndef LD_INIT_SWITCH
2037 write_c_file_glob (stream
, name
);
2040 write_c_file_stat (stream
, name
);
2041 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2044 #ifdef COLLECT_EXPORT_LIST
2046 write_aix_file (stream
, list
)
2050 for (; list
; list
= list
->next
)
2052 fputs (list
->name
, stream
);
2053 putc ('\n', stream
);
2058 #ifdef OBJECT_FORMAT_NONE
2060 /* Generic version to scan the name list of the loaded program for
2061 the symbols g++ uses for static constructors and destructors.
2063 The constructor table begins at __CTOR_LIST__ and contains a count
2064 of the number of pointers (or -1 if the constructors are built in a
2065 separate section by the linker), followed by the pointers to the
2066 constructor functions, terminated with a null pointer. The
2067 destructor table has the same format, and begins at __DTOR_LIST__. */
2070 scan_prog_file (prog_name
, which_pass
)
2071 const char *prog_name
;
2072 enum pass which_pass
;
2074 void (*int_handler
) PARAMS ((int));
2075 void (*quit_handler
) PARAMS ((int));
2076 char *real_nm_argv
[4];
2077 const char **nm_argv
= (const char **) real_nm_argv
;
2084 if (which_pass
== PASS_SECOND
)
2087 /* If we do not have an `nm', complain. */
2088 if (nm_file_name
== 0)
2089 fatal ("cannot find `nm'");
2091 nm_argv
[argc
++] = nm_file_name
;
2092 if (NM_FLAGS
[0] != '\0')
2093 nm_argv
[argc
++] = NM_FLAGS
;
2095 nm_argv
[argc
++] = prog_name
;
2096 nm_argv
[argc
++] = (char *) 0;
2098 if (pipe (pipe_fd
) < 0)
2099 fatal_perror ("pipe");
2101 inf
= fdopen (pipe_fd
[0], "r");
2102 if (inf
== (FILE *) 0)
2103 fatal_perror ("fdopen");
2105 /* Trace if needed. */
2108 const char **p_argv
;
2111 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2112 fprintf (stderr
, " %s", str
);
2114 fprintf (stderr
, "\n");
2120 /* Spawn child nm on pipe */
2123 fatal_perror (VFORK_STRING
);
2125 if (pid
== 0) /* child context */
2128 if (dup2 (pipe_fd
[1], 1) < 0)
2129 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2131 if (close (pipe_fd
[0]) < 0)
2132 fatal_perror ("close %d", pipe_fd
[0]);
2134 if (close (pipe_fd
[1]) < 0)
2135 fatal_perror ("close %d", pipe_fd
[1]);
2137 execv (nm_file_name
, real_nm_argv
);
2138 fatal_perror ("execvp %s", nm_file_name
);
2141 /* Parent context from here on. */
2142 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2144 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2147 if (close (pipe_fd
[1]) < 0)
2148 fatal_perror ("close %d", pipe_fd
[1]);
2151 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2153 /* Read each line of nm output. */
2154 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2159 /* If it contains a constructor or destructor name, add the name
2160 to the appropriate list. */
2162 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2163 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2170 /* Find the end of the symbol name.
2171 Do not include `|', because Encore nm can tack that on the end. */
2172 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2178 switch (is_ctor_dtor (name
))
2181 if (which_pass
!= PASS_LIB
)
2182 add_to_list (&constructors
, name
);
2186 if (which_pass
!= PASS_LIB
)
2187 add_to_list (&destructors
, name
);
2191 if (which_pass
!= PASS_LIB
)
2192 fatal ("init function found in object %s", prog_name
);
2193 #ifndef LD_INIT_SWITCH
2194 add_to_list (&constructors
, name
);
2199 if (which_pass
!= PASS_LIB
)
2200 fatal ("fini function found in object %s", prog_name
);
2201 #ifndef LD_FINI_SWITCH
2202 add_to_list (&destructors
, name
);
2207 if (which_pass
!= PASS_LIB
)
2208 add_to_list (&frame_tables
, name
);
2211 default: /* not a constructor or destructor */
2216 fprintf (stderr
, "\t%s\n", buf
);
2220 fprintf (stderr
, "\n");
2222 if (fclose (inf
) != 0)
2223 fatal_perror ("fclose");
2225 do_wait (nm_file_name
);
2227 signal (SIGINT
, int_handler
);
2229 signal (SIGQUIT
, quit_handler
);
2233 #if SUNOS4_SHARED_LIBRARIES
2235 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2236 that the output file depends upon and their initialization/finalization
2237 routines, if any. */
2242 #include <sys/mman.h>
2243 #include <sys/param.h>
2245 #include <sys/dir.h>
2247 /* pointers to the object file */
2248 unsigned object
; /* address of memory mapped file */
2249 unsigned objsize
; /* size of memory mapped to file */
2250 char * code
; /* pointer to code segment */
2251 char * data
; /* pointer to data segment */
2252 struct nlist
*symtab
; /* pointer to symbol table */
2253 struct link_dynamic
*ld
;
2254 struct link_dynamic_2
*ld_2
;
2255 struct head libraries
;
2257 /* Map the file indicated by NAME into memory and store its address. */
2259 static void mapfile
PARAMS ((const char *));
2267 if ((fp
= open (name
, O_RDONLY
)) == -1)
2268 fatal ("unable to open file '%s'", name
);
2269 if (fstat (fp
, &s
) == -1)
2270 fatal ("unable to stat file '%s'", name
);
2272 objsize
= s
.st_size
;
2273 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2275 if (object
== (unsigned)-1)
2276 fatal ("unable to mmap file '%s'", name
);
2281 /* Helpers for locatelib. */
2283 static const char *libname
;
2285 static int libselect
PARAMS ((struct direct
*));
2291 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2294 /* If one file has an additional numeric extension past LIBNAME, then put
2295 that one first in the sort. If both files have additional numeric
2296 extensions, then put the one with the higher number first in the sort.
2298 We must verify that the extension is numeric, because Sun saves the
2299 original versions of patched libraries with a .FCS extension. Files with
2300 invalid extensions must go last in the sort, so that they will not be used. */
2301 static int libcompare
PARAMS ((struct direct
**, struct direct
**));
2305 struct direct
**d1
, **d2
;
2307 int i1
, i2
= strlen (libname
);
2308 char *e1
= (*d1
)->d_name
+ i2
;
2309 char *e2
= (*d2
)->d_name
+ i2
;
2311 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2312 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2316 i1
= strtol (e1
, &e1
, 10);
2317 i2
= strtol (e2
, &e2
, 10);
2324 /* It has a valid numeric extension, prefer this one. */
2325 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2327 /* It has an invalid numeric extension, must prefer the other one. */
2333 /* It has a valid numeric extension, prefer this one. */
2334 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2336 /* It has an invalid numeric extension, must prefer the other one. */
2344 /* Given the name NAME of a dynamic dependency, find its pathname and add
2345 it to the list of libraries. */
2346 static void locatelib
PARAMS ((const char *));
2352 static const char **l
;
2354 char buf
[MAXPATHLEN
];
2362 /* counting elements in array, need 1 extra for null */
2364 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2368 for (; *ld_rules
!= 0; ld_rules
++)
2369 if (*ld_rules
== ':')
2371 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2372 ldr
= xstrdup (ld_rules
);
2374 p
= getenv ("LD_LIBRARY_PATH");
2379 for (q
= p
; *q
!= 0; q
++)
2384 l
= (const char **) xmalloc ((cnt
+ 3) * sizeof (char *));
2389 for (; *ldr
!= 0; ldr
++)
2399 for (; *q
!= 0; q
++)
2406 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2409 *pp
++ = "/usr/local/lib";
2413 for (pp
= l
; *pp
!= 0 ; pp
++)
2415 struct direct
**namelist
;
2417 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2419 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2420 add_to_list (&libraries
, buf
);
2422 fprintf (stderr
, "%s\n", buf
);
2429 notice ("not found\n");
2431 fatal ("dynamic dependency %s not found", name
);
2435 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2436 that it depends upon and any constructors or destructors they contain. */
2439 scan_libraries (prog_name
)
2440 const char *prog_name
;
2442 struct exec
*header
;
2444 struct link_object
*lo
;
2445 char buff
[MAXPATHLEN
];
2448 mapfile (prog_name
);
2449 header
= (struct exec
*)object
;
2450 if (N_BADMAG (*header
))
2451 fatal ("bad magic number in file '%s'", prog_name
);
2452 if (header
->a_dynamic
== 0)
2455 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2456 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2457 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2459 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2462 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2468 ld
= (struct link_dynamic
*) data
;
2473 notice ("dynamic dependencies.\n");
2475 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2476 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2477 lo
= (struct link_object
*) lo
->lo_next
)
2480 lo
= (struct link_object
*) ((long) lo
+ code
);
2481 name
= (char *) (code
+ lo
->lo_name
);
2485 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2486 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2492 fprintf (stderr
, "\t%s\n", name
);
2493 add_to_list (&libraries
, name
);
2498 fprintf (stderr
, "\n");
2500 /* now iterate through the library list adding their symbols to
2502 for (list
= libraries
.first
; list
; list
= list
->next
)
2503 scan_prog_file (list
->name
, PASS_LIB
);
2506 #else /* SUNOS4_SHARED_LIBRARIES */
2509 /* Use the List Dynamic Dependencies program to find shared libraries that
2510 the output file depends upon and their initialization/finalization
2511 routines, if any. */
2514 scan_libraries (prog_name
)
2515 const char *prog_name
;
2517 static struct head libraries
; /* list of shared libraries found */
2519 void (*int_handler
) PARAMS ((int));
2520 void (*quit_handler
) PARAMS ((int));
2521 char *real_ldd_argv
[4];
2522 const char **ldd_argv
= (const char **) real_ldd_argv
;
2529 /* If we do not have an `ldd', complain. */
2530 if (ldd_file_name
== 0)
2532 error ("cannot find `ldd'");
2536 ldd_argv
[argc
++] = ldd_file_name
;
2537 ldd_argv
[argc
++] = prog_name
;
2538 ldd_argv
[argc
++] = (char *) 0;
2540 if (pipe (pipe_fd
) < 0)
2541 fatal_perror ("pipe");
2543 inf
= fdopen (pipe_fd
[0], "r");
2544 if (inf
== (FILE *) 0)
2545 fatal_perror ("fdopen");
2547 /* Trace if needed. */
2550 const char **p_argv
;
2553 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2554 fprintf (stderr
, " %s", str
);
2556 fprintf (stderr
, "\n");
2562 /* Spawn child ldd on pipe */
2565 fatal_perror (VFORK_STRING
);
2567 if (pid
== 0) /* child context */
2570 if (dup2 (pipe_fd
[1], 1) < 0)
2571 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2573 if (close (pipe_fd
[0]) < 0)
2574 fatal_perror ("close %d", pipe_fd
[0]);
2576 if (close (pipe_fd
[1]) < 0)
2577 fatal_perror ("close %d", pipe_fd
[1]);
2579 execv (ldd_file_name
, real_ldd_argv
);
2580 fatal_perror ("execv %s", ldd_file_name
);
2583 /* Parent context from here on. */
2584 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2586 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2589 if (close (pipe_fd
[1]) < 0)
2590 fatal_perror ("close %d", pipe_fd
[1]);
2593 notice ("\nldd output with constructors/destructors.\n");
2595 /* Read each line of ldd output. */
2596 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2599 char *name
, *end
, *p
= buf
;
2601 /* Extract names of libraries and add to list. */
2602 PARSE_LDD_OUTPUT (p
);
2607 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2608 fatal ("dynamic dependency %s not found", buf
);
2610 /* Find the end of the symbol name. */
2612 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2617 if (access (name
, R_OK
) == 0)
2618 add_to_list (&libraries
, name
);
2620 fatal ("unable to open dynamic dependency '%s'", buf
);
2623 fprintf (stderr
, "\t%s\n", buf
);
2626 fprintf (stderr
, "\n");
2628 if (fclose (inf
) != 0)
2629 fatal_perror ("fclose");
2631 do_wait (ldd_file_name
);
2633 signal (SIGINT
, int_handler
);
2635 signal (SIGQUIT
, quit_handler
);
2638 /* now iterate through the library list adding their symbols to
2640 for (list
= libraries
.first
; list
; list
= list
->next
)
2641 scan_prog_file (list
->name
, PASS_LIB
);
2644 #endif /* LDD_SUFFIX */
2645 #endif /* SUNOS4_SHARED_LIBRARIES */
2647 #endif /* OBJECT_FORMAT_NONE */
2651 * COFF specific stuff.
2654 #ifdef OBJECT_FORMAT_COFF
2656 #if defined(EXTENDED_COFF)
2658 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2659 # define GCC_SYMENT SYMR
2660 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2661 # define GCC_SYMINC(X) (1)
2662 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2663 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2667 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2668 # define GCC_SYMENT SYMENT
2669 # define GCC_OK_SYMBOL(X) \
2670 (((X).n_sclass == C_EXT) && \
2671 ((X).n_scnum > N_UNDEF) && \
2673 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2674 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2675 # define GCC_UNDEF_SYMBOL(X) \
2676 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2677 # define GCC_SYMINC(X) ((X).n_numaux+1)
2678 # define GCC_SYMZERO(X) 0
2680 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2682 # define GCC_CHECK_HDR(X) \
2683 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2684 || (HEADER (X).f_magic == 0767 && aix64_flag))
2686 # define GCC_CHECK_HDR(X) \
2687 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2688 || (HEADER (X).f_magic == 0757 && aix64_flag))
2693 extern char *ldgetname ();
2695 /* COFF version to scan the name list of the loaded program for
2696 the symbols g++ uses for static constructors and destructors.
2698 The constructor table begins at __CTOR_LIST__ and contains a count
2699 of the number of pointers (or -1 if the constructors are built in a
2700 separate section by the linker), followed by the pointers to the
2701 constructor functions, terminated with a null pointer. The
2702 destructor table has the same format, and begins at __DTOR_LIST__. */
2705 scan_prog_file (prog_name
, which_pass
)
2706 const char *prog_name
;
2707 enum pass which_pass
;
2709 LDFILE
*ldptr
= NULL
;
2710 int sym_index
, sym_count
;
2713 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2716 #ifdef COLLECT_EXPORT_LIST
2717 /* We do not need scanning for some standard C libraries. */
2718 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2721 /* On AIX we have a loop, because there is not much difference
2722 between an object and an archive. This trick allows us to
2723 eliminate scan_libraries() function. */
2727 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2728 non-const char * filename parameter, even though it will not
2729 modify that string. So we must cast away const-ness here,
2730 which will cause -Wcast-qual to burp. */
2731 if ((ldptr
= ldopen ((char *)prog_name
, ldptr
)) != NULL
)
2733 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2734 fatal ("%s: not a COFF file", prog_name
);
2736 if (GCC_CHECK_HDR (ldptr
))
2738 sym_count
= GCC_SYMBOLS (ldptr
);
2739 sym_index
= GCC_SYMZERO (ldptr
);
2741 #ifdef COLLECT_EXPORT_LIST
2742 /* Is current archive member a shared object? */
2743 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2746 while (sym_index
< sym_count
)
2750 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2752 sym_index
+= GCC_SYMINC (symbol
);
2754 if (GCC_OK_SYMBOL (symbol
))
2758 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2759 continue; /* should never happen */
2761 #ifdef XCOFF_DEBUGGING_INFO
2762 /* All AIX function names have a duplicate entry
2763 beginning with a dot. */
2768 switch (is_ctor_dtor (name
))
2772 add_to_list (&constructors
, name
);
2773 #ifdef COLLECT_EXPORT_LIST
2774 if (which_pass
== PASS_OBJ
)
2775 add_to_list (&exports
, name
);
2781 add_to_list (&destructors
, name
);
2782 #ifdef COLLECT_EXPORT_LIST
2783 if (which_pass
== PASS_OBJ
)
2784 add_to_list (&exports
, name
);
2788 #ifdef COLLECT_EXPORT_LIST
2790 #ifndef LD_INIT_SWITCH
2792 add_to_list (&constructors
, name
);
2797 #ifndef LD_INIT_SWITCH
2799 add_to_list (&destructors
, name
);
2806 add_to_list (&frame_tables
, name
);
2807 #ifdef COLLECT_EXPORT_LIST
2808 if (which_pass
== PASS_OBJ
)
2809 add_to_list (&exports
, name
);
2813 default: /* not a constructor or destructor */
2814 #ifdef COLLECT_EXPORT_LIST
2815 /* If we are building a shared object on AIX we need
2816 to explicitly export all global symbols. */
2819 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2820 add_to_list (&exports
, name
);
2827 #if !defined(EXTENDED_COFF)
2828 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2829 symbol
.n_scnum
, symbol
.n_sclass
,
2830 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2834 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2835 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2840 #ifdef COLLECT_EXPORT_LIST
2843 /* If archive contains both 32-bit and 64-bit objects,
2844 we want to skip objects in other mode so mismatch normal. */
2846 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2847 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2853 fatal ("%s: cannot open as COFF file", prog_name
);
2855 #ifdef COLLECT_EXPORT_LIST
2856 /* On AIX loop continues while there are more members in archive. */
2858 while (ldclose (ldptr
) == FAILURE
);
2860 /* Otherwise we simply close ldptr. */
2861 (void) ldclose(ldptr
);
2864 #endif /* OBJECT_FORMAT_COFF */
2866 #ifdef COLLECT_EXPORT_LIST
2867 /* Given a library name without "lib" prefix, this function
2868 returns a full library name including a path. */
2870 resolve_lib_name (name
)
2876 for (i
= 0; libpaths
[i
]; i
++)
2877 if (libpaths
[i
]->max_len
> l
)
2878 l
= libpaths
[i
]->max_len
;
2880 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2882 for (i
= 0; libpaths
[i
]; i
++)
2884 struct prefix_list
*list
= libpaths
[i
]->plist
;
2885 for (; list
; list
= list
->next
)
2887 /* The following lines are needed because path_prefix list
2888 may contain directories both with trailing '/' and
2891 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
2893 for (j
= 0; libexts
[j
]; j
++)
2895 sprintf (lib_buf
, "%s%slib%s.%s",
2896 list
->prefix
, p
, name
, libexts
[j
]);
2897 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
2898 if (file_exists (lib_buf
))
2900 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
2907 fprintf (stderr
, "not found\n");
2909 fatal ("library lib%s not found", name
);
2913 /* Array of standard AIX libraries which should not
2914 be scanned for ctors/dtors. */
2915 static const char *const aix_std_libs
[] = {
2923 "/usr/lib/libc_r.a",
2924 "/usr/lib/libm_r.a",
2925 "/usr/lib/threads/libc.a",
2926 "/usr/ccs/lib/libc.a",
2927 "/usr/ccs/lib/libm.a",
2928 "/usr/ccs/lib/libc_r.a",
2929 "/usr/ccs/lib/libm_r.a",
2933 /* This function checks the filename and returns 1
2934 if this name matches the location of a standard AIX library. */
2936 ignore_library (name
)
2939 const char *const *p
= &aix_std_libs
[0];
2940 while (*p
++ != NULL
)
2941 if (! strcmp (name
, *p
)) return 1;
2944 #endif /* COLLECT_EXPORT_LIST */
2948 * OSF/rose specific stuff.
2951 #ifdef OBJECT_FORMAT_ROSE
2953 /* Union of the various load commands */
2955 typedef union load_union
2957 ldc_header_t hdr
; /* common header */
2958 load_cmd_map_command_t map
; /* map indexing other load cmds */
2959 interpreter_command_t iprtr
; /* interpreter pathname */
2960 strings_command_t str
; /* load commands strings section */
2961 region_command_t region
; /* region load command */
2962 reloc_command_t reloc
; /* relocation section */
2963 package_command_t pkg
; /* package load command */
2964 symbols_command_t sym
; /* symbol sections */
2965 entry_command_t ent
; /* program start section */
2966 gen_info_command_t info
; /* object information */
2967 func_table_command_t func
; /* function constructors/destructors */
2970 /* Structure to point to load command and data section in memory. */
2972 typedef struct load_all
2974 load_union_t
*load
; /* load command */
2975 char *section
; /* pointer to section */
2978 /* Structure to contain information about a file mapped into memory. */
2982 char *start
; /* start of map */
2983 char *name
; /* filename */
2984 long size
; /* size of the file */
2985 long rounded_size
; /* size rounded to page boundary */
2986 int fd
; /* file descriptor */
2987 int rw
; /* != 0 if opened read/write */
2988 int use_mmap
; /* != 0 if mmap'ed */
2991 extern int decode_mach_o_hdr ();
2992 extern int encode_mach_o_hdr ();
2994 static void add_func_table
PARAMS ((mo_header_t
*, load_all_t
*,
2995 symbol_info_t
*, int));
2996 static void print_header
PARAMS ((mo_header_t
*));
2997 static void print_load_command
PARAMS ((load_union_t
*, size_t, int));
2998 static void bad_header
PARAMS ((int));
2999 static struct file_info
*read_file
PARAMS ((const char *, int, int));
3000 static void end_file
PARAMS ((struct file_info
*));
3002 /* OSF/rose specific version to scan the name list of the loaded
3003 program for the symbols g++ uses for static constructors and
3006 The constructor table begins at __CTOR_LIST__ and contains a count
3007 of the number of pointers (or -1 if the constructors are built in a
3008 separate section by the linker), followed by the pointers to the
3009 constructor functions, terminated with a null pointer. The
3010 destructor table has the same format, and begins at __DTOR_LIST__. */
3013 scan_prog_file (prog_name
, which_pass
)
3014 const char *prog_name
;
3015 enum pass which_pass
;
3019 load_all_t
*load_array
;
3020 load_all_t
*load_end
;
3021 load_all_t
*load_cmd
;
3022 int symbol_load_cmds
;
3028 struct file_info
*obj_file
;
3030 mo_lcid_t cmd_strings
= -1;
3031 symbol_info_t
*main_sym
= 0;
3032 int rw
= (which_pass
!= PASS_FIRST
);
3034 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3036 fatal_perror ("open %s", prog_name
);
3038 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3039 obj
= obj_file
->start
;
3041 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3042 if (status
!= MO_HDR_CONV_SUCCESS
)
3043 bad_header (status
);
3046 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3047 since the hardware will automatically swap bytes for us on loading little endian
3050 #ifndef CROSS_COMPILE
3051 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3052 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3053 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3054 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3055 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3056 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3057 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3059 fatal ("incompatibilities between object file & expected values");
3064 print_header (&hdr
);
3066 offset
= hdr
.moh_first_cmd_off
;
3067 load_end
= load_array
3068 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3070 /* Build array of load commands, calculating the offsets */
3071 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3073 load_union_t
*load_hdr
; /* load command header */
3075 load_cmd
= load_end
++;
3076 load_hdr
= (load_union_t
*) (obj
+ offset
);
3078 /* If modifying the program file, copy the header. */
3081 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3082 memcpy ((char *)ptr
, (char *)load_hdr
, load_hdr
->hdr
.ldci_cmd_size
);
3085 /* null out old command map, because we will rewrite at the end. */
3086 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3088 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3089 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3093 load_cmd
->load
= load_hdr
;
3094 if (load_hdr
->hdr
.ldci_section_off
> 0)
3095 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3098 print_load_command (load_hdr
, offset
, i
);
3100 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3103 /* If the last command is the load command map and is not undefined,
3104 decrement the count of load commands. */
3105 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3108 hdr
.moh_n_load_cmds
--;
3111 /* Go through and process each symbol table section. */
3112 symbol_load_cmds
= 0;
3113 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3115 load_union_t
*load_hdr
= load_cmd
->load
;
3117 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3123 const char *kind
= "unknown";
3125 switch (load_hdr
->sym
.symc_kind
)
3127 case SYMC_IMPORTS
: kind
= "imports"; break;
3128 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3129 case SYMC_STABS
: kind
= "stabs"; break;
3132 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3133 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3136 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3139 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3140 if (str_sect
== (char *) 0)
3141 fatal ("string section missing");
3143 if (load_cmd
->section
== (char *) 0)
3144 fatal ("section pointer missing");
3146 num_syms
= load_hdr
->sym
.symc_nentries
;
3147 for (i
= 0; i
< num_syms
; i
++)
3149 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3150 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3157 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3159 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3169 switch (is_ctor_dtor (name
))
3172 add_to_list (&constructors
, name
);
3176 add_to_list (&destructors
, name
);
3179 default: /* not a constructor or destructor */
3185 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3186 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3191 if (symbol_load_cmds
== 0)
3192 fatal ("no symbol table found");
3194 /* Update the program file now, rewrite header and load commands. At present,
3195 we assume that there is enough space after the last load command to insert
3196 one more. Since the first section written out is page aligned, and the
3197 number of load commands is small, this is ok for the present. */
3201 load_union_t
*load_map
;
3204 if (cmd_strings
== -1)
3205 fatal ("no cmd_strings found");
3207 /* Add __main to initializer list.
3208 If we are building a program instead of a shared library, do not
3209 do anything, since in the current version, you cannot do mallocs
3210 and such in the constructors. */
3212 if (main_sym
!= (symbol_info_t
*) 0
3213 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3214 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3217 notice ("\nUpdating header and load commands.\n\n");
3219 hdr
.moh_n_load_cmds
++;
3220 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3222 /* Create new load command map. */
3224 notice ("load command map, %d cmds, new size %ld.\n",
3225 (int) hdr
.moh_n_load_cmds
, (long) size
);
3227 load_map
= (load_union_t
*) xcalloc (1, size
);
3228 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3229 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3230 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3231 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3232 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3234 offset
= hdr
.moh_first_cmd_off
;
3235 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3237 load_map
->map
.lcm_map
[i
] = offset
;
3238 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3239 hdr
.moh_load_map_cmd_off
= offset
;
3241 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3244 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3247 print_header (&hdr
);
3250 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3251 if (status
!= MO_HDR_CONV_SUCCESS
)
3252 bad_header (status
);
3255 notice ("writing load commands.\n\n");
3257 /* Write load commands */
3258 offset
= hdr
.moh_first_cmd_off
;
3259 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3261 load_union_t
*load_hdr
= load_array
[i
].load
;
3262 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3265 print_load_command (load_hdr
, offset
, i
);
3267 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3272 end_file (obj_file
);
3274 if (close (prog_fd
))
3275 fatal_perror ("close %s", prog_name
);
3278 fprintf (stderr
, "\n");
3282 /* Add a function table to the load commands to call a function
3283 on initiation or termination of the process. */
3286 add_func_table (hdr_p
, load_array
, sym
, type
)
3287 mo_header_t
*hdr_p
; /* pointer to global header */
3288 load_all_t
*load_array
; /* array of ptrs to load cmds */
3289 symbol_info_t
*sym
; /* pointer to symbol entry */
3290 int type
; /* fntc_type value */
3292 /* Add a new load command. */
3293 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3294 int load_index
= num_cmds
- 1;
3295 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3296 load_union_t
*ptr
= xcalloc (1, size
);
3297 load_all_t
*load_cmd
;
3300 /* Set the unresolved address bit in the header to force the loader to be
3301 used, since kernel exec does not call the initialization functions. */
3302 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3304 load_cmd
= &load_array
[load_index
];
3305 load_cmd
->load
= ptr
;
3306 load_cmd
->section
= (char *) 0;
3308 /* Fill in func table load command. */
3309 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3310 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3311 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3312 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3313 ptr
->func
.fntc_type
= type
;
3314 ptr
->func
.fntc_nentries
= 1;
3316 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3317 /* Is the symbol already expressed as (region, offset)? */
3318 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3320 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3321 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3324 /* If not, figure out which region it's in. */
3327 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3330 for (i
= 0; i
< load_index
; i
++)
3332 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3334 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3336 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3337 && addr
>= region_ptr
->regc_addr
.vm_addr
3338 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3340 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3341 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3349 fatal ("could not convert 0x%l.8x into a region", addr
);
3353 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3354 type
== FNTC_INITIALIZATION
? "init" : "term",
3355 (int) ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3356 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3357 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3362 /* Print the global header for an OSF/rose object. */
3365 print_header (hdr_ptr
)
3366 mo_header_t
*hdr_ptr
;
3368 fprintf (stderr
, "\nglobal header:\n");
3369 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3370 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3371 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3372 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3373 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3374 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3375 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3376 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3377 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3378 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3379 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3380 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3381 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3382 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3383 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3385 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3386 fprintf (stderr
, ", relocatable");
3388 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3389 fprintf (stderr
, ", linkable");
3391 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3392 fprintf (stderr
, ", execable");
3394 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3395 fprintf (stderr
, ", executable");
3397 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3398 fprintf (stderr
, ", unresolved");
3400 fprintf (stderr
, "\n\n");
3405 /* Print a short summary of a load command. */
3408 print_load_command (load_hdr
, offset
, number
)
3409 load_union_t
*load_hdr
;
3413 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3414 const char *type_str
= (char *) 0;
3418 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3419 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3420 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3421 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3422 case LDC_REGION
: type_str
= "REGION"; break;
3423 case LDC_RELOC
: type_str
= "RELOC"; break;
3424 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3425 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3426 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3427 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3428 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3432 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3434 (long) load_hdr
->hdr
.ldci_cmd_size
,
3436 (long) load_hdr
->hdr
.ldci_section_off
,
3437 (long) load_hdr
->hdr
.ldci_section_len
);
3439 if (type_str
== (char *) 0)
3440 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3442 else if (type
!= LDC_REGION
)
3443 fprintf (stderr
, ", ty: %s\n", type_str
);
3447 const char *region
= "";
3448 switch (load_hdr
->region
.regc_usage_type
)
3450 case REG_TEXT_T
: region
= ", .text"; break;
3451 case REG_DATA_T
: region
= ", .data"; break;
3452 case REG_BSS_T
: region
= ", .bss"; break;
3453 case REG_GLUE_T
: region
= ", .glue"; break;
3454 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3455 case REG_RDATA_T
: region
= ", .rdata"; break;
3456 case REG_SDATA_T
: region
= ", .sdata"; break;
3457 case REG_SBSS_T
: region
= ", .sbss"; break;
3461 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3463 (long) load_hdr
->region
.regc_vm_addr
,
3464 (long) load_hdr
->region
.regc_vm_size
,
3472 /* Fatal error when {en,de}code_mach_o_header fails. */
3480 case MO_ERROR_BAD_MAGIC
: fatal ("bad magic number");
3481 case MO_ERROR_BAD_HDR_VERS
: fatal ("bad header version");
3482 case MO_ERROR_BAD_RAW_HDR_VERS
: fatal ("bad raw header version");
3483 case MO_ERROR_BUF2SML
: fatal ("raw header buffer too small");
3484 case MO_ERROR_OLD_RAW_HDR_FILE
: fatal ("old raw header file");
3485 case MO_ERROR_UNSUPPORTED_VERS
: fatal ("unsupported version");
3487 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3492 /* Read a file into a memory buffer. */
3494 static struct file_info
*
3495 read_file (name
, fd
, rw
)
3496 const char *name
; /* filename */
3497 int fd
; /* file descriptor */
3498 int rw
; /* read/write */
3500 struct stat stat_pkt
;
3501 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3503 static int page_size
;
3506 if (fstat (fd
, &stat_pkt
) < 0)
3507 fatal_perror ("fstat %s", name
);
3510 p
->size
= stat_pkt
.st_size
;
3511 p
->rounded_size
= stat_pkt
.st_size
;
3517 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3520 page_size
= sysconf (_SC_PAGE_SIZE
);
3522 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3523 p
->start
= mmap ((caddr_t
) 0,
3524 (rw
) ? p
->rounded_size
: p
->size
,
3525 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3526 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3530 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3534 #endif /* USE_MMAP */
3539 fprintf (stderr
, "read %s\n", name
);
3542 p
->start
= xmalloc (p
->size
);
3543 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3544 fatal_perror ("lseek %s 0", name
);
3546 len
= read (fd
, p
->start
, p
->size
);
3548 fatal_perror ("read %s", name
);
3551 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3557 /* Do anything necessary to write a file back from memory. */
3561 struct file_info
*ptr
; /* file information block */
3569 fprintf (stderr
, "msync %s\n", ptr
->name
);
3571 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3572 fatal_perror ("msync %s", ptr
->name
);
3576 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3578 if (munmap (ptr
->start
, ptr
->size
))
3579 fatal_perror ("munmap %s", ptr
->name
);
3582 #endif /* USE_MMAP */
3589 fprintf (stderr
, "write %s\n", ptr
->name
);
3591 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3592 fatal_perror ("lseek %s 0", ptr
->name
);
3594 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3596 fatal_perror ("write %s", ptr
->name
);
3598 if (len
!= ptr
->size
)
3599 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3608 #endif /* OBJECT_FORMAT_ROSE */