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, 2003 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. */
31 #include "coretypes.h"
34 #if ! defined( SIGCHLD ) && defined( SIGCLD )
35 # define SIGCHLD SIGCLD
38 #ifdef vfork /* Autoconf may define this to fork for us. */
39 # define VFORK_STRING "fork"
41 # define VFORK_STRING "vfork"
47 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
48 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
51 #ifndef LIBRARY_PATH_ENV
52 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
63 /* On certain systems, we have code that works by scanning the object file
64 directly. But this code uses system-specific header files and library
65 functions, so turn it off in a cross-compiler. Likewise, the names of
66 the utilities are not correct for a cross-compiler; we have to hope that
67 cross-versions are in the proper directories. */
70 #undef SUNOS4_SHARED_LIBRARIES
71 #undef OBJECT_FORMAT_COFF
72 #undef OBJECT_FORMAT_ROSE
74 #undef REAL_LD_FILE_NAME
75 #undef REAL_NM_FILE_NAME
76 #undef REAL_STRIP_FILE_NAME
79 /* If we cannot use a special method, use the ordinary one:
80 run nm to find what symbols are present.
81 In a cross-compiler, this means you need a cross nm,
82 but that is not quite as unpleasant as special headers. */
84 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
85 #define OBJECT_FORMAT_NONE
88 #ifdef OBJECT_FORMAT_COFF
97 /* Many versions of ldfcn.h define these. */
105 /* Some systems have an ISCOFF macro, but others do not. In some cases
106 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
107 that either do not have an ISCOFF macro in /usr/include or for those
108 where it is wrong. */
111 #define MY_ISCOFF(X) ISCOFF (X)
114 #endif /* OBJECT_FORMAT_COFF */
116 #ifdef OBJECT_FORMAT_ROSE
123 #include <sys/mman.h>
127 #include <mach_o_format.h>
128 #include <mach_o_header.h>
129 #include <mach_o_vals.h>
130 #include <mach_o_types.h>
132 #endif /* OBJECT_FORMAT_ROSE */
134 #ifdef OBJECT_FORMAT_NONE
136 /* Default flags to pass to nm. */
138 #define NM_FLAGS "-n"
141 #endif /* OBJECT_FORMAT_NONE */
143 /* Some systems use __main in a way incompatible with its use in gcc, in these
144 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
145 give the same symbol without quotes for an alternative entry point. */
147 #define NAME__MAIN "__main"
150 /* This must match tree.h. */
151 #define DEFAULT_INIT_PRIORITY 65535
153 #ifndef COLLECT_SHARED_INIT_FUNC
154 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
155 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
157 #ifndef COLLECT_SHARED_FINI_FUNC
158 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
159 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
162 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
163 #define SCAN_LIBRARIES
167 int do_collecting
= 1;
169 int do_collecting
= 0;
172 /* Nonzero if we should suppress the automatic demangling of identifiers
173 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
176 /* Linked lists of constructor and destructor names. */
192 /* Enumeration giving which pass this is for scanning the program file. */
195 PASS_FIRST
, /* without constructors */
196 PASS_OBJ
, /* individual objects */
197 PASS_LIB
, /* looking for shared libraries */
198 PASS_SECOND
/* with constructors linked in */
201 int vflag
; /* true if -v */
202 static int rflag
; /* true if -r */
203 static int strip_flag
; /* true if -s */
204 #ifdef COLLECT_EXPORT_LIST
205 static int export_flag
; /* true if -bE */
206 static int aix64_flag
; /* true if -b64 */
209 int debug
; /* true if -debug */
211 static int shared_obj
; /* true if -shared */
213 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
214 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
215 #ifdef COLLECT_EXPORT_LIST
216 static const char *export_file
; /* <xxx>.x for AIX export list. */
218 const char *ldout
; /* File for ld errors. */
219 static const char *output_file
; /* Output file for ld. */
220 static const char *nm_file_name
; /* pathname of nm */
222 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
224 static const char *strip_file_name
; /* pathname of strip */
225 const char *c_file_name
; /* pathname of gcc */
226 static char *initname
, *fininame
; /* names of init and fini funcs */
228 static struct head constructors
; /* list of constructors found */
229 static struct head destructors
; /* list of destructors found */
230 #ifdef COLLECT_EXPORT_LIST
231 static struct head exports
; /* list of exported symbols */
233 static struct head frame_tables
; /* list of frame unwind info tables */
235 struct obstack temporary_obstack
;
236 char * temporary_firstobj
;
238 /* Holds the return value of pexecute and fork. */
241 /* Structure to hold all the directories in which to search for files to
246 const char *prefix
; /* String to prepend to the path. */
247 struct prefix_list
*next
; /* Next in linked list. */
252 struct prefix_list
*plist
; /* List of prefixes to try */
253 int max_len
; /* Max length of a prefix in PLIST */
254 const char *name
; /* Name of this list (used in config stuff) */
257 #ifdef COLLECT_EXPORT_LIST
258 /* Lists to keep libraries to be scanned for global constructors/destructors. */
259 static struct head libs
; /* list of libraries */
260 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
261 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
262 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
263 &libpath_lib_dirs
, NULL
};
264 static const char *const libexts
[3] = {"a", "so", NULL
}; /* possible library extensions */
267 static void handler
PARAMS ((int));
268 static int is_ctor_dtor
PARAMS ((const char *));
269 static char *find_a_file
PARAMS ((struct path_prefix
*, const char *));
270 static void add_prefix
PARAMS ((struct path_prefix
*, const char *));
271 static void prefix_from_env
PARAMS ((const char *, struct path_prefix
*));
272 static void prefix_from_string
PARAMS ((const char *, struct path_prefix
*));
273 static void do_wait
PARAMS ((const char *));
274 static void fork_execute
PARAMS ((const char *, char **));
275 static void maybe_unlink
PARAMS ((const char *));
276 static void add_to_list
PARAMS ((struct head
*, const char *));
277 static int extract_init_priority
PARAMS ((const char *));
278 static void sort_ids
PARAMS ((struct head
*));
279 static void write_list
PARAMS ((FILE *, const char *, struct id
*));
280 #ifdef COLLECT_EXPORT_LIST
281 static void dump_list
PARAMS ((FILE *, const char *, struct id
*));
284 static void dump_prefix_list
PARAMS ((FILE *, const char *, struct prefix_list
*));
286 static void write_list_with_asm
PARAMS ((FILE *, const char *, struct id
*));
287 static void write_c_file
PARAMS ((FILE *, const char *));
288 static void write_c_file_stat
PARAMS ((FILE *, const char *));
289 #ifndef LD_INIT_SWITCH
290 static void write_c_file_glob
PARAMS ((FILE *, const char *));
292 static void scan_prog_file
PARAMS ((const char *, enum pass
));
293 #ifdef SCAN_LIBRARIES
294 static void scan_libraries
PARAMS ((const char *));
296 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
297 static int is_in_args
PARAMS ((const char *, const char **, const char **));
299 #ifdef COLLECT_EXPORT_LIST
301 static int is_in_list
PARAMS ((const char *, struct id
*));
303 static void write_aix_file
PARAMS ((FILE *, struct id
*));
304 static char *resolve_lib_name
PARAMS ((const char *));
306 static char *extract_string
PARAMS ((const char **));
309 static int dup2
PARAMS ((int, int));
322 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
325 close (fdtmp
[--fdx
]);
329 #endif /* ! HAVE_DUP2 */
331 /* Delete tempfiles and exit function. */
334 collect_exit (status
)
337 if (c_file
!= 0 && c_file
[0])
338 maybe_unlink (c_file
);
340 if (o_file
!= 0 && o_file
[0])
341 maybe_unlink (o_file
);
343 #ifdef COLLECT_EXPORT_LIST
344 if (export_file
!= 0 && export_file
[0])
345 maybe_unlink (export_file
);
348 if (ldout
!= 0 && ldout
[0])
351 maybe_unlink (ldout
);
354 if (status
!= 0 && output_file
!= 0 && output_file
[0])
355 maybe_unlink (output_file
);
361 /* Notify user of a non-error. */
363 notice (const char *msgid
, ...)
367 va_start (ap
, msgid
);
368 vfprintf (stderr
, _(msgid
), ap
);
372 /* Die when sys call fails. */
375 fatal_perror (const char * msgid
, ...)
380 va_start (ap
, msgid
);
381 fprintf (stderr
, "collect2: ");
382 vfprintf (stderr
, _(msgid
), ap
);
383 fprintf (stderr
, ": %s\n", xstrerror (e
));
386 collect_exit (FATAL_EXIT_CODE
);
392 fatal (const char * msgid
, ...)
396 va_start (ap
, msgid
);
397 fprintf (stderr
, "collect2: ");
398 vfprintf (stderr
, _(msgid
), ap
);
399 fprintf (stderr
, "\n");
402 collect_exit (FATAL_EXIT_CODE
);
405 /* Write error message. */
408 error (const char * msgid
, ...)
412 va_start (ap
, msgid
);
413 fprintf (stderr
, "collect2: ");
414 vfprintf (stderr
, _(msgid
), ap
);
415 fprintf (stderr
, "\n");
419 /* In case obstack is linked in, and abort is defined to fancy_abort,
420 provide a default entry. */
425 fatal ("internal error");
432 if (c_file
!= 0 && c_file
[0])
433 maybe_unlink (c_file
);
435 if (o_file
!= 0 && o_file
[0])
436 maybe_unlink (o_file
);
438 if (ldout
!= 0 && ldout
[0])
439 maybe_unlink (ldout
);
441 #ifdef COLLECT_EXPORT_LIST
442 if (export_file
!= 0 && export_file
[0])
443 maybe_unlink (export_file
);
446 signal (signo
, SIG_DFL
);
447 kill (getpid (), signo
);
455 return access (name
, R_OK
) == 0;
458 /* Parse a reasonable subset of shell quoting syntax. */
475 obstack_1grow (&temporary_obstack
, c
);
476 else if (! inside
&& c
== ' ')
478 else if (! inside
&& c
== '\\')
483 obstack_1grow (&temporary_obstack
, c
);
486 obstack_1grow (&temporary_obstack
, '\0');
488 return obstack_finish (&temporary_obstack
);
495 FILE *stream
= fopen (name
, "r");
502 while (c
= getc (stream
),
503 c
!= EOF
&& (ISIDNUM (c
) || c
== '$' || c
== '.'))
504 obstack_1grow (&temporary_obstack
, c
);
505 if (obstack_object_size (&temporary_obstack
) > 0)
507 const char *word
, *p
;
509 obstack_1grow (&temporary_obstack
, '\0');
510 word
= obstack_finish (&temporary_obstack
);
513 ++word
, putc ('.', stderr
);
515 if (!strncmp (p
, USER_LABEL_PREFIX
, strlen (USER_LABEL_PREFIX
)))
516 p
+= strlen (USER_LABEL_PREFIX
);
521 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
| DMGL_VERBOSE
);
526 fputs (result
, stderr
);
528 diff
= strlen (word
) - strlen (result
);
529 while (diff
> 0 && c
== ' ')
530 --diff
, putc (' ', stderr
);
531 while (diff
< 0 && c
== ' ')
532 ++diff
, c
= getc (stream
);
537 fputs (word
, stderr
);
540 obstack_free (&temporary_obstack
, temporary_firstobj
);
549 /* Decide whether the given symbol is: a constructor (1), a destructor
550 (2), a routine in a shared object that calls all the constructors
551 (3) or destructors (4), a DWARF exception-handling table (5), or
552 nothing special (0). */
558 struct names
{ const char *const name
; const int len
; const int ret
;
559 const int two_underscores
; };
561 const struct names
*p
;
563 const char *orig_s
= s
;
565 static const struct names special
[] = {
566 #ifndef NO_DOLLAR_IN_LABEL
567 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
568 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
570 #ifndef NO_DOT_IN_LABEL
571 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
572 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
573 #endif /* NO_DOT_IN_LABEL */
574 #endif /* NO_DOLLAR_IN_LABEL */
575 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
576 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
577 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
578 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
579 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
583 while ((ch
= *s
) == '_')
589 for (p
= &special
[0]; p
->len
> 0; p
++)
592 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
593 && strncmp(s
, p
->name
, p
->len
) == 0)
601 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
602 and one from the PATH variable. */
604 static struct path_prefix cpath
, path
;
607 /* This is the name of the target machine. We use it to form the name
608 of the files to execute. */
610 static const char *const target_machine
= TARGET_MACHINE
;
613 /* Search for NAME using prefix list PPREFIX. We only look for executable
616 Return 0 if not found, otherwise return its name, allocated with malloc. */
619 find_a_file (pprefix
, name
)
620 struct path_prefix
*pprefix
;
624 struct prefix_list
*pl
;
625 int len
= pprefix
->max_len
+ strlen (name
) + 1;
628 fprintf (stderr
, "Looking for '%s'\n", name
);
630 #ifdef HOST_EXECUTABLE_SUFFIX
631 len
+= strlen (HOST_EXECUTABLE_SUFFIX
);
634 temp
= xmalloc (len
);
636 /* Determine the filename to execute (special case for absolute paths). */
639 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
640 || (*name
&& name
[1] == ':')
644 if (access (name
, X_OK
) == 0)
649 fprintf (stderr
, " - found: absolute path\n");
654 #ifdef HOST_EXECUTABLE_SUFFIX
655 /* Some systems have a suffix for executable files.
656 So try appending that. */
658 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
660 if (access (temp
, X_OK
) == 0)
665 fprintf (stderr
, " - failed to locate using absolute path\n");
668 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
672 strcpy (temp
, pl
->prefix
);
675 if (stat (temp
, &st
) >= 0
676 && ! S_ISDIR (st
.st_mode
)
677 && access (temp
, X_OK
) == 0)
680 #ifdef HOST_EXECUTABLE_SUFFIX
681 /* Some systems have a suffix for executable files.
682 So try appending that. */
683 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
685 if (stat (temp
, &st
) >= 0
686 && ! S_ISDIR (st
.st_mode
)
687 && access (temp
, X_OK
) == 0)
692 if (debug
&& pprefix
->plist
== NULL
)
693 fprintf (stderr
, " - failed: no entries in prefix list\n");
699 /* Add an entry for PREFIX to prefix list PPREFIX. */
702 add_prefix (pprefix
, prefix
)
703 struct path_prefix
*pprefix
;
706 struct prefix_list
*pl
, **prev
;
711 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
716 prev
= &pprefix
->plist
;
718 /* Keep track of the longest prefix */
720 len
= strlen (prefix
);
721 if (len
> pprefix
->max_len
)
722 pprefix
->max_len
= len
;
724 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
725 pl
->prefix
= xstrdup (prefix
);
730 pl
->next
= (struct prefix_list
*) 0;
734 /* Take the value of the environment variable ENV, break it into a path, and
735 add of the entries to PPREFIX. */
738 prefix_from_env (env
, pprefix
)
740 struct path_prefix
*pprefix
;
743 GET_ENVIRONMENT (p
, env
);
746 prefix_from_string (p
, pprefix
);
750 prefix_from_string (p
, pprefix
)
752 struct path_prefix
*pprefix
;
754 const char *startp
, *endp
;
755 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
758 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
763 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
765 strncpy (nstore
, startp
, endp
-startp
);
768 strcpy (nstore
, "./");
770 else if (! IS_DIR_SEPARATOR (endp
[-1]))
772 nstore
[endp
-startp
] = DIR_SEPARATOR
;
773 nstore
[endp
-startp
+1] = 0;
776 nstore
[endp
-startp
] = 0;
779 fprintf (stderr
, " - add prefix: %s\n", nstore
);
781 add_prefix (pprefix
, nstore
);
784 endp
= startp
= endp
+ 1;
793 int main
PARAMS ((int, char *[]));
799 static const char *const ld_suffix
= "ld";
800 static const char *const real_ld_suffix
= "real-ld";
801 static const char *const collect_ld_suffix
= "collect-ld";
802 static const char *const nm_suffix
= "nm";
803 static const char *const gnm_suffix
= "gnm";
805 static const char *const ldd_suffix
= LDD_SUFFIX
;
807 static const char *const strip_suffix
= "strip";
808 static const char *const gstrip_suffix
= "gstrip";
811 /* If we look for a program in the compiler directories, we just use
812 the short name, since these directories are already system-specific.
813 But it we look for a program in the system directories, we need to
814 qualify the program name with the target machine. */
816 const char *const full_ld_suffix
=
817 concat(target_machine
, "-", ld_suffix
, NULL
);
818 const char *const full_nm_suffix
=
819 concat (target_machine
, "-", nm_suffix
, NULL
);
820 const char *const full_gnm_suffix
=
821 concat (target_machine
, "-", gnm_suffix
, NULL
);
823 const char *const full_ldd_suffix
=
824 concat (target_machine
, "-", ldd_suffix
, NULL
);
826 const char *const full_strip_suffix
=
827 concat (target_machine
, "-", strip_suffix
, NULL
);
828 const char *const full_gstrip_suffix
=
829 concat (target_machine
, "-", gstrip_suffix
, NULL
);
831 const char *const full_ld_suffix
= ld_suffix
;
832 const char *const full_nm_suffix
= nm_suffix
;
833 const char *const full_gnm_suffix
= gnm_suffix
;
835 const char *const full_ldd_suffix
= ldd_suffix
;
837 const char *const full_strip_suffix
= strip_suffix
;
838 const char *const full_gstrip_suffix
= gstrip_suffix
;
839 #endif /* CROSS_COMPILE */
843 #ifdef COLLECT_EXPORT_LIST
846 const char *ld_file_name
;
857 int num_c_args
= argc
+9;
859 no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
861 /* Suppress demangling by the real linker, which may be broken. */
862 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
864 #if defined (COLLECT2_HOST_INITIALIZATION)
865 /* Perform system dependent initialization, if necessary. */
866 COLLECT2_HOST_INITIALIZATION
;
870 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
871 receive the signal. A different setting is inheritable */
872 signal (SIGCHLD
, SIG_DFL
);
877 /* Do not invoke xcalloc before this point, since locale needs to be
878 set first, in case a diagnostic is issued. */
880 ld1
= (const char **)(ld1_argv
= (char **) xcalloc(sizeof (char *), argc
+3));
881 ld2
= (const char **)(ld2_argv
= (char **) xcalloc(sizeof (char *), argc
+10));
882 object
= (const char **)(object_lst
= (char **) xcalloc(sizeof (char *), argc
));
888 /* Parse command line early for instances of -debug. This allows
889 the debug flag to be set before functions like find_a_file()
894 for (i
= 1; argv
[i
] != NULL
; i
++)
895 if (! strcmp (argv
[i
], "-debug"))
900 #ifndef DEFAULT_A_OUT_NAME
901 output_file
= "a.out";
903 output_file
= DEFAULT_A_OUT_NAME
;
906 obstack_begin (&temporary_obstack
, 0);
907 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
909 current_demangling_style
= auto_demangling
;
910 p
= getenv ("COLLECT_GCC_OPTIONS");
913 const char *q
= extract_string (&p
);
914 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
917 obstack_free (&temporary_obstack
, temporary_firstobj
);
919 /* -fno-exceptions -w */
922 c_ptr
= (const char **)
923 (c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
));
926 fatal ("no arguments");
929 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
930 signal (SIGQUIT
, handler
);
932 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
933 signal (SIGINT
, handler
);
935 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
936 signal (SIGALRM
, handler
);
939 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
940 signal (SIGHUP
, handler
);
942 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
943 signal (SIGSEGV
, handler
);
945 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
946 signal (SIGBUS
, handler
);
949 /* Extract COMPILER_PATH and PATH into our prefix list. */
950 prefix_from_env ("COMPILER_PATH", &cpath
);
951 prefix_from_env ("PATH", &path
);
953 /* Try to discover a valid linker/nm/strip to use. */
955 /* Maybe we know the right file to use (if not cross). */
957 #ifdef DEFAULT_LINKER
958 if (access (DEFAULT_LINKER
, X_OK
) == 0)
959 ld_file_name
= DEFAULT_LINKER
;
960 if (ld_file_name
== 0)
962 #ifdef REAL_LD_FILE_NAME
963 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
964 if (ld_file_name
== 0)
966 /* Search the (target-specific) compiler dirs for ld'. */
967 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
968 /* Likewise for `collect-ld'. */
969 if (ld_file_name
== 0)
970 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
971 /* Search the compiler directories for `ld'. We have protection against
972 recursive calls in find_a_file. */
973 if (ld_file_name
== 0)
974 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
975 /* Search the ordinary system bin directories
976 for `ld' (if native linking) or `TARGET-ld' (if cross). */
977 if (ld_file_name
== 0)
978 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
980 #ifdef REAL_NM_FILE_NAME
981 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
982 if (nm_file_name
== 0)
984 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
985 if (nm_file_name
== 0)
986 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
987 if (nm_file_name
== 0)
988 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
989 if (nm_file_name
== 0)
990 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
993 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
994 if (ldd_file_name
== 0)
995 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
998 #ifdef REAL_STRIP_FILE_NAME
999 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1000 if (strip_file_name
== 0)
1002 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1003 if (strip_file_name
== 0)
1004 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1005 if (strip_file_name
== 0)
1006 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1007 if (strip_file_name
== 0)
1008 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1010 /* Determine the full path name of the C compiler to use. */
1011 c_file_name
= getenv ("COLLECT_GCC");
1012 if (c_file_name
== 0)
1014 #ifdef CROSS_COMPILE
1015 c_file_name
= concat (target_machine
, "-gcc", NULL
);
1017 c_file_name
= "gcc";
1021 p
= find_a_file (&cpath
, c_file_name
);
1023 /* Here it should be safe to use the system search path since we should have
1024 already qualified the name of the compiler when it is needed. */
1026 p
= find_a_file (&path
, c_file_name
);
1031 *ld1
++ = *ld2
++ = ld_file_name
;
1033 /* Make temp file names. */
1034 c_file
= make_temp_file (".c");
1035 o_file
= make_temp_file (".o");
1036 #ifdef COLLECT_EXPORT_LIST
1037 export_file
= make_temp_file (".x");
1039 ldout
= make_temp_file (".ld");
1040 *c_ptr
++ = c_file_name
;
1047 #ifdef COLLECT_EXPORT_LIST
1048 /* Generate a list of directories from LIBPATH. */
1049 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1050 /* Add to this list also two standard directories where
1051 AIX loader always searches for libraries. */
1052 add_prefix (&libpath_lib_dirs
, "/lib");
1053 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1056 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1058 AIX support needs to know if -shared has been specified before
1059 parsing commandline arguments. */
1061 p
= getenv ("COLLECT_GCC_OPTIONS");
1064 const char *q
= extract_string (&p
);
1065 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1066 *c_ptr
++ = xstrdup (q
);
1067 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1068 *c_ptr
++ = xstrdup (q
);
1069 if (strcmp (q
, "-shared") == 0)
1071 if (*q
== '-' && q
[1] == 'B')
1073 *c_ptr
++ = xstrdup (q
);
1076 q
= extract_string (&p
);
1077 *c_ptr
++ = xstrdup (q
);
1081 obstack_free (&temporary_obstack
, temporary_firstobj
);
1082 *c_ptr
++ = "-fno-exceptions";
1085 /* !!! When GCC calls collect2,
1086 it does not know whether it is calling collect2 or ld.
1087 So collect2 cannot meaningfully understand any options
1088 except those ld understands.
1089 If you propose to make GCC pass some other option,
1090 just imagine what will happen if ld is really ld!!! */
1092 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1093 /* After the first file, put in the c++ rt0. */
1096 while ((arg
= *++argv
) != (char *) 0)
1098 *ld1
++ = *ld2
++ = arg
;
1104 #ifdef COLLECT_EXPORT_LIST
1105 /* We want to disable automatic exports on AIX when user
1106 explicitly puts an export list in command line */
1108 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1110 else if (arg
[2] == '6' && arg
[3] == '4')
1116 if (!strcmp (arg
, "-debug"))
1118 /* Already parsed. */
1127 /* place o_file BEFORE this argument! */
1133 #ifdef COLLECT_EXPORT_LIST
1135 /* Resolving full library name. */
1136 const char *s
= resolve_lib_name (arg
+2);
1138 /* Saving a full library name. */
1139 add_to_list (&libs
, s
);
1144 #ifdef COLLECT_EXPORT_LIST
1145 /* Saving directories where to search for libraries. */
1147 add_prefix (&cmdline_lib_dirs
, arg
+2);
1150 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1152 if (is_in_args (arg
, (const char **) ld1_argv
, ld1
-1))
1155 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1160 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1162 #ifdef SWITCHES_NEED_SPACES
1163 && ! strchr (SWITCHES_NEED_SPACES
, arg
[1])
1167 output_file
= &arg
[2];
1176 if (arg
[2] == '\0' && do_collecting
)
1178 /* We must strip after the nm run, otherwise C++ linking
1179 will not work. Thus we strip in the second ld run, or
1180 else with strip if there is no second ld run. */
1192 else if ((p
= strrchr (arg
, '.')) != (char *) 0
1193 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1194 || strcmp (p
, ".so") == 0 || strcmp (p
, ".lo") == 0
1195 || strcmp (p
, ".obj") == 0))
1204 /* place o_file BEFORE this argument! */
1210 if (p
[1] == 'o' || p
[1] == 'l')
1212 #ifdef COLLECT_EXPORT_LIST
1213 /* libraries can be specified directly, i.e. without -l flag. */
1216 /* Saving a full library name. */
1217 add_to_list (&libs
, arg
);
1223 #ifdef COLLECT_EXPORT_LIST
1224 /* This is added only for debugging purposes. */
1227 fprintf (stderr
, "List of libraries:\n");
1228 dump_list (stderr
, "\t", libs
.first
);
1231 /* The AIX linker will discard static constructors in object files if
1232 nothing else in the file is referenced, so look at them first. */
1234 const char **export_object_lst
= (const char **)object_lst
;
1236 while (export_object_lst
< object
)
1237 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1240 struct id
*list
= libs
.first
;
1242 for (; list
; list
= list
->next
)
1243 scan_prog_file (list
->name
, PASS_FIRST
);
1248 char *buf
= concat ("-bE:", export_file
, NULL
);
1253 exportf
= fopen (export_file
, "w");
1254 if (exportf
== (FILE *) 0)
1255 fatal_perror ("fopen %s", export_file
);
1256 write_aix_file (exportf
, exports
.first
);
1257 if (fclose (exportf
))
1258 fatal_perror ("fclose %s", export_file
);
1263 *c_ptr
= *ld1
= *object
= (char *) 0;
1267 notice ("collect2 version %s", version_string
);
1268 #ifdef TARGET_VERSION
1271 fprintf (stderr
, "\n");
1277 fprintf (stderr
, "ld_file_name = %s\n",
1278 (ld_file_name
? ld_file_name
: "not found"));
1279 fprintf (stderr
, "c_file_name = %s\n",
1280 (c_file_name
? c_file_name
: "not found"));
1281 fprintf (stderr
, "nm_file_name = %s\n",
1282 (nm_file_name
? nm_file_name
: "not found"));
1284 fprintf (stderr
, "ldd_file_name = %s\n",
1285 (ldd_file_name
? ldd_file_name
: "not found"));
1287 fprintf (stderr
, "strip_file_name = %s\n",
1288 (strip_file_name
? strip_file_name
: "not found"));
1289 fprintf (stderr
, "c_file = %s\n",
1290 (c_file
? c_file
: "not found"));
1291 fprintf (stderr
, "o_file = %s\n",
1292 (o_file
? o_file
: "not found"));
1294 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1296 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1298 ptr
= getenv ("COLLECT_GCC");
1300 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1302 ptr
= getenv ("COMPILER_PATH");
1304 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1306 ptr
= getenv (LIBRARY_PATH_ENV
);
1308 fprintf (stderr
, "%-20s= %s\n", LIBRARY_PATH_ENV
, ptr
);
1310 fprintf (stderr
, "\n");
1313 /* Load the program, searching all libraries and attempting to provide
1314 undefined symbols from repository information. */
1316 /* On AIX we do this later. */
1317 #ifndef COLLECT_EXPORT_LIST
1318 do_tlink (ld1_argv
, object_lst
);
1321 /* If -r or they will be run via some other method, do not build the
1322 constructor or destructor list, just return now. */
1324 #ifndef COLLECT_EXPORT_LIST
1329 #ifdef COLLECT_EXPORT_LIST
1330 /* Do the link we avoided above if we are exiting. */
1331 do_tlink (ld1_argv
, object_lst
);
1333 /* But make sure we delete the export file we may have created. */
1334 if (export_file
!= 0 && export_file
[0])
1335 maybe_unlink (export_file
);
1337 maybe_unlink (c_file
);
1338 maybe_unlink (o_file
);
1342 /* Examine the namelist with nm and search it for static constructors
1343 and destructors to call.
1344 Write the constructor and destructor tables to a .s file and reload. */
1346 /* On AIX we already scanned for global constructors/destructors. */
1347 #ifndef COLLECT_EXPORT_LIST
1348 scan_prog_file (output_file
, PASS_FIRST
);
1351 #ifdef SCAN_LIBRARIES
1352 scan_libraries (output_file
);
1357 notice ("%d constructor(s) found\n", constructors
.number
);
1358 notice ("%d destructor(s) found\n", destructors
.number
);
1359 notice ("%d frame table(s) found\n", frame_tables
.number
);
1362 if (constructors
.number
== 0 && destructors
.number
== 0
1363 && frame_tables
.number
== 0
1364 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1365 /* If we will be running these functions ourselves, we want to emit
1366 stubs into the shared library so that we do not have to relink
1367 dependent programs when we add static objects. */
1372 #ifdef COLLECT_EXPORT_LIST
1373 /* Do tlink without additional code generation */
1374 do_tlink (ld1_argv
, object_lst
);
1376 /* Strip now if it was requested on the command line. */
1379 char **real_strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1380 const char ** strip_argv
= (const char **) real_strip_argv
;
1382 strip_argv
[0] = strip_file_name
;
1383 strip_argv
[1] = output_file
;
1384 strip_argv
[2] = (char *) 0;
1385 fork_execute ("strip", real_strip_argv
);
1388 #ifdef COLLECT_EXPORT_LIST
1389 maybe_unlink (export_file
);
1391 maybe_unlink (c_file
);
1392 maybe_unlink (o_file
);
1396 /* Sort ctor and dtor lists by priority. */
1397 sort_ids (&constructors
);
1398 sort_ids (&destructors
);
1400 maybe_unlink(output_file
);
1401 outf
= fopen (c_file
, "w");
1402 if (outf
== (FILE *) 0)
1403 fatal_perror ("fopen %s", c_file
);
1405 write_c_file (outf
, c_file
);
1408 fatal_perror ("fclose %s", c_file
);
1410 /* Tell the linker that we have initializer and finalizer functions. */
1411 #ifdef LD_INIT_SWITCH
1412 #ifdef COLLECT_EXPORT_LIST
1413 *ld2
++ = concat (LD_INIT_SWITCH
, ":", initname
, ":", fininame
, NULL
);
1415 *ld2
++ = LD_INIT_SWITCH
;
1417 *ld2
++ = LD_FINI_SWITCH
;
1422 #ifdef COLLECT_EXPORT_LIST
1425 /* If we did not add export flag to link arguments before, add it to
1426 second link phase now. No new exports should have been added. */
1427 if (! exports
.first
)
1428 *ld2
++ = concat ("-bE:", export_file
, NULL
);
1430 add_to_list (&exports
, initname
);
1431 add_to_list (&exports
, fininame
);
1432 add_to_list (&exports
, "_GLOBAL__DI");
1433 add_to_list (&exports
, "_GLOBAL__DD");
1434 exportf
= fopen (export_file
, "w");
1435 if (exportf
== (FILE *) 0)
1436 fatal_perror ("fopen %s", export_file
);
1437 write_aix_file (exportf
, exports
.first
);
1438 if (fclose (exportf
))
1439 fatal_perror ("fclose %s", export_file
);
1443 /* End of arguments to second link phase. */
1448 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1449 output_file
, c_file
);
1450 write_c_file (stderr
, "stderr");
1451 fprintf (stderr
, "========== end of c_file\n\n");
1452 #ifdef COLLECT_EXPORT_LIST
1453 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1454 write_aix_file (stderr
, exports
.first
);
1455 fprintf (stderr
, "========== end of export_file\n\n");
1459 /* Assemble the constructor and destructor tables.
1460 Link the tables in with the rest of the program. */
1462 fork_execute ("gcc", c_argv
);
1463 #ifdef COLLECT_EXPORT_LIST
1464 /* On AIX we must call tlink because of possible templates resolution */
1465 do_tlink (ld2_argv
, object_lst
);
1467 /* Otherwise, simply call ld because tlink is already done */
1468 fork_execute ("ld", ld2_argv
);
1470 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1471 constructors/destructors in shared libraries. */
1472 scan_prog_file (output_file
, PASS_SECOND
);
1475 maybe_unlink (c_file
);
1476 maybe_unlink (o_file
);
1478 #ifdef COLLECT_EXPORT_LIST
1479 maybe_unlink (export_file
);
1486 /* Wait for a process to finish, and exit if a nonzero status is found. */
1494 pwait (pid
, &status
, 0);
1497 if (WIFSIGNALED (status
))
1499 int sig
= WTERMSIG (status
);
1500 error ("%s terminated with signal %d [%s]%s",
1501 prog
, sig
, strsignal(sig
),
1502 WCOREDUMP(status
) ? ", core dumped" : "");
1503 collect_exit (FATAL_EXIT_CODE
);
1506 if (WIFEXITED (status
))
1507 return WEXITSTATUS (status
);
1516 int ret
= collect_wait (prog
);
1519 error ("%s returned %d exit status", prog
, ret
);
1525 /* Execute a program, and wait for the reply. */
1528 collect_execute (prog
, argv
, redir
)
1535 int redir_handle
= -1;
1536 int stdout_save
= -1;
1537 int stderr_save
= -1;
1545 fprintf (stderr
, "%s", argv
[0]);
1547 notice ("[cannot find %s]", prog
);
1549 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1550 fprintf (stderr
, " %s", str
);
1552 fprintf (stderr
, "\n");
1558 /* If we cannot find a program we need, complain error. Do this here
1559 since we might not end up needing something that we could not find. */
1562 fatal ("cannot find `%s'", prog
);
1566 /* Open response file. */
1567 redir_handle
= open (redir
, O_WRONLY
| O_TRUNC
| O_CREAT
);
1569 /* Duplicate the stdout and stderr file handles
1570 so they can be restored later. */
1571 stdout_save
= dup (STDOUT_FILENO
);
1572 if (stdout_save
== -1)
1573 fatal_perror ("redirecting stdout: %s", redir
);
1574 stderr_save
= dup (STDERR_FILENO
);
1575 if (stderr_save
== -1)
1576 fatal_perror ("redirecting stdout: %s", redir
);
1578 /* Redirect stdout & stderr to our response file. */
1579 dup2 (redir_handle
, STDOUT_FILENO
);
1580 dup2 (redir_handle
, STDERR_FILENO
);
1583 pid
= pexecute (argv
[0], argv
, argv
[0], NULL
, &errmsg_fmt
, &errmsg_arg
,
1584 (PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
));
1588 /* Restore stdout and stderr to their previous settings. */
1589 dup2 (stdout_save
, STDOUT_FILENO
);
1590 dup2 (stderr_save
, STDERR_FILENO
);
1592 /* Close response file. */
1593 close (redir_handle
);
1597 fatal_perror (errmsg_fmt
, errmsg_arg
);
1601 fork_execute (prog
, argv
)
1605 collect_execute (prog
, argv
, NULL
);
1609 /* Unlink a file unless we are debugging. */
1618 notice ("[Leaving %s]\n", file
);
1622 static long sequence_number
= 0;
1624 /* Add a name to a linked list. */
1627 add_to_list (head_ptr
, name
)
1628 struct head
*head_ptr
;
1632 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1634 strcpy (newid
->name
, name
);
1636 if (head_ptr
->first
)
1637 head_ptr
->last
->next
= newid
;
1639 head_ptr
->first
= newid
;
1641 /* Check for duplicate symbols. */
1642 for (p
= head_ptr
->first
;
1643 strcmp (name
, p
->name
) != 0;
1648 head_ptr
->last
->next
= 0;
1653 newid
->sequence
= ++sequence_number
;
1654 head_ptr
->last
= newid
;
1658 /* Grab the init priority number from an init function name that
1659 looks like "_GLOBAL_.I.12345.foo". */
1662 extract_init_priority (name
)
1667 while (name
[pos
] == '_')
1669 pos
+= 10; /* strlen ("GLOBAL__X_") */
1671 /* Extract init_p number from ctor/dtor name. */
1672 pri
= atoi (name
+ pos
);
1673 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1676 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1677 ctors will be run from right to left, dtors from left to right. */
1681 struct head
*head_ptr
;
1683 /* id holds the current element to insert. id_next holds the next
1684 element to insert. id_ptr iterates through the already sorted elements
1685 looking for the place to insert id. */
1686 struct id
*id
, *id_next
, **id_ptr
;
1688 id
= head_ptr
->first
;
1690 /* We don't have any sorted elements yet. */
1691 head_ptr
->first
= NULL
;
1693 for (; id
; id
= id_next
)
1696 id
->sequence
= extract_init_priority (id
->name
);
1698 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1700 /* If the sequence numbers are the same, we put the id from the
1701 file later on the command line later in the list. */
1702 || id
->sequence
> (*id_ptr
)->sequence
1703 /* Hack: do lexical compare, too.
1704 || (id->sequence == (*id_ptr)->sequence
1705 && strcmp (id->name, (*id_ptr)->name) > 0) */
1714 /* Now set the sequence numbers properly so write_c_file works. */
1715 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1716 id
->sequence
= ++sequence_number
;
1719 /* Write: `prefix', the names on list LIST, `suffix'. */
1722 write_list (stream
, prefix
, list
)
1729 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1734 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1735 /* Given a STRING, return nonzero if it occurs in the list in range
1736 [ARGS_BEGIN,ARGS_END). */
1739 is_in_args (string
, args_begin
, args_end
)
1741 const char **args_begin
;
1742 const char **args_end
;
1744 const char **args_pointer
;
1745 for (args_pointer
= args_begin
; args_pointer
!= args_end
; ++args_pointer
)
1746 if (strcmp (string
, *args_pointer
) == 0)
1750 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1752 #ifdef COLLECT_EXPORT_LIST
1753 /* This function is really used only on AIX, but may be useful. */
1756 is_in_list (prefix
, list
)
1762 if (!strcmp (prefix
, list
->name
)) return 1;
1768 #endif /* COLLECT_EXPORT_LIST */
1770 /* Added for debugging purpose. */
1771 #ifdef COLLECT_EXPORT_LIST
1773 dump_list (stream
, prefix
, list
)
1780 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1788 dump_prefix_list (stream
, prefix
, list
)
1791 struct prefix_list
*list
;
1795 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1802 write_list_with_asm (stream
, prefix
, list
)
1809 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1810 prefix
, list
->sequence
, list
->name
);
1815 /* Write out the constructor and destructor tables statically (for a shared
1816 object), along with the functions to execute them. */
1819 write_c_file_stat (stream
, name
)
1821 const char *name ATTRIBUTE_UNUSED
;
1825 int frames
= (frame_tables
.number
> 0);
1827 /* Figure out name of output_file, stripping off .so version. */
1828 p
= strrchr (output_file
, '/');
1844 if (strncmp (q
, ".so", 3) == 0)
1853 /* q points to null at end of the string (or . of the .so version) */
1854 prefix
= xmalloc (q
- p
+ 1);
1855 strncpy (prefix
, p
, q
- p
);
1857 for (r
= prefix
; *r
; r
++)
1858 if (!ISALNUM ((unsigned char)*r
))
1861 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1862 output_file
, prefix
);
1864 initname
= concat ("_GLOBAL__FI_", prefix
, NULL
);
1865 fininame
= concat ("_GLOBAL__FD_", prefix
, NULL
);
1869 /* Write the tables as C code */
1871 fprintf (stream
, "static int count;\n");
1872 fprintf (stream
, "typedef void entry_pt();\n");
1873 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1877 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1879 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1880 write_list (stream
, "\t\t&", frame_tables
.first
);
1881 fprintf (stream
, "\t0\n};\n");
1883 /* This must match what's in frame.h. */
1884 fprintf (stream
, "struct object {\n");
1885 fprintf (stream
, " void *pc_begin;\n");
1886 fprintf (stream
, " void *pc_end;\n");
1887 fprintf (stream
, " void *fde_begin;\n");
1888 fprintf (stream
, " void *fde_array;\n");
1889 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1890 fprintf (stream
, " struct object *next;\n");
1891 fprintf (stream
, "};\n");
1893 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1894 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1896 fprintf (stream
, "static void reg_frame () {\n");
1897 fprintf (stream
, "\tstatic struct object ob;\n");
1898 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1899 fprintf (stream
, "\t}\n");
1901 fprintf (stream
, "static void dereg_frame () {\n");
1902 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1903 fprintf (stream
, "\t}\n");
1906 fprintf (stream
, "void %s() {\n", initname
);
1907 if (constructors
.number
> 0 || frames
)
1909 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1910 write_list (stream
, "\t\t", constructors
.first
);
1912 fprintf (stream
, "\treg_frame,\n");
1913 fprintf (stream
, "\t};\n");
1914 fprintf (stream
, "\tentry_pt **p;\n");
1915 fprintf (stream
, "\tif (count++ != 0) return;\n");
1916 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1917 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1920 fprintf (stream
, "\t++count;\n");
1921 fprintf (stream
, "}\n");
1922 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1923 fprintf (stream
, "void %s() {\n", fininame
);
1924 if (destructors
.number
> 0 || frames
)
1926 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1927 write_list (stream
, "\t\t", destructors
.first
);
1929 fprintf (stream
, "\tdereg_frame,\n");
1930 fprintf (stream
, "\t};\n");
1931 fprintf (stream
, "\tentry_pt **p;\n");
1932 fprintf (stream
, "\tif (--count != 0) return;\n");
1933 fprintf (stream
, "\tp = dtors;\n");
1934 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
1935 destructors
.number
+ frames
);
1937 fprintf (stream
, "}\n");
1941 COLLECT_SHARED_INIT_FUNC(stream
, initname
);
1942 COLLECT_SHARED_FINI_FUNC(stream
, fininame
);
1946 /* Write the constructor/destructor tables. */
1948 #ifndef LD_INIT_SWITCH
1950 write_c_file_glob (stream
, name
)
1952 const char *name ATTRIBUTE_UNUSED
;
1954 /* Write the tables as C code */
1956 int frames
= (frame_tables
.number
> 0);
1958 fprintf (stream
, "typedef void entry_pt();\n\n");
1960 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1964 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1966 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1967 write_list (stream
, "\t\t&", frame_tables
.first
);
1968 fprintf (stream
, "\t0\n};\n");
1970 /* This must match what's in frame.h. */
1971 fprintf (stream
, "struct object {\n");
1972 fprintf (stream
, " void *pc_begin;\n");
1973 fprintf (stream
, " void *pc_end;\n");
1974 fprintf (stream
, " void *fde_begin;\n");
1975 fprintf (stream
, " void *fde_array;\n");
1976 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1977 fprintf (stream
, " struct object *next;\n");
1978 fprintf (stream
, "};\n");
1980 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1981 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1983 fprintf (stream
, "static void reg_frame () {\n");
1984 fprintf (stream
, "\tstatic struct object ob;\n");
1985 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1986 fprintf (stream
, "\t}\n");
1988 fprintf (stream
, "static void dereg_frame () {\n");
1989 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1990 fprintf (stream
, "\t}\n");
1993 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
1994 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
1995 write_list (stream
, "\t", constructors
.first
);
1997 fprintf (stream
, "\treg_frame,\n");
1998 fprintf (stream
, "\t0\n};\n\n");
2000 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2002 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2003 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2004 write_list (stream
, "\t", destructors
.first
);
2006 fprintf (stream
, "\tdereg_frame,\n");
2007 fprintf (stream
, "\t0\n};\n\n");
2009 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2010 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2012 #endif /* ! LD_INIT_SWITCH */
2015 write_c_file (stream
, name
)
2019 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2020 #ifndef LD_INIT_SWITCH
2022 write_c_file_glob (stream
, name
);
2025 write_c_file_stat (stream
, name
);
2026 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2029 #ifdef COLLECT_EXPORT_LIST
2031 write_aix_file (stream
, list
)
2035 for (; list
; list
= list
->next
)
2037 fputs (list
->name
, stream
);
2038 putc ('\n', stream
);
2043 #ifdef OBJECT_FORMAT_NONE
2045 /* Generic version to scan the name list of the loaded program for
2046 the symbols g++ uses for static constructors and destructors.
2048 The constructor table begins at __CTOR_LIST__ and contains a count
2049 of the number of pointers (or -1 if the constructors are built in a
2050 separate section by the linker), followed by the pointers to the
2051 constructor functions, terminated with a null pointer. The
2052 destructor table has the same format, and begins at __DTOR_LIST__. */
2055 scan_prog_file (prog_name
, which_pass
)
2056 const char *prog_name
;
2057 enum pass which_pass
;
2059 void (*int_handler
) PARAMS ((int));
2060 void (*quit_handler
) PARAMS ((int));
2061 char *real_nm_argv
[4];
2062 const char **nm_argv
= (const char **) real_nm_argv
;
2068 if (which_pass
== PASS_SECOND
)
2071 /* If we do not have an `nm', complain. */
2072 if (nm_file_name
== 0)
2073 fatal ("cannot find `nm'");
2075 nm_argv
[argc
++] = nm_file_name
;
2076 if (NM_FLAGS
[0] != '\0')
2077 nm_argv
[argc
++] = NM_FLAGS
;
2079 nm_argv
[argc
++] = prog_name
;
2080 nm_argv
[argc
++] = (char *) 0;
2082 if (pipe (pipe_fd
) < 0)
2083 fatal_perror ("pipe");
2085 inf
= fdopen (pipe_fd
[0], "r");
2086 if (inf
== (FILE *) 0)
2087 fatal_perror ("fdopen");
2089 /* Trace if needed. */
2092 const char **p_argv
;
2095 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2096 fprintf (stderr
, " %s", str
);
2098 fprintf (stderr
, "\n");
2104 /* Spawn child nm on pipe */
2107 fatal_perror (VFORK_STRING
);
2109 if (pid
== 0) /* child context */
2112 if (dup2 (pipe_fd
[1], 1) < 0)
2113 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2115 if (close (pipe_fd
[0]) < 0)
2116 fatal_perror ("close %d", pipe_fd
[0]);
2118 if (close (pipe_fd
[1]) < 0)
2119 fatal_perror ("close %d", pipe_fd
[1]);
2121 execv (nm_file_name
, real_nm_argv
);
2122 fatal_perror ("execv %s", nm_file_name
);
2125 /* Parent context from here on. */
2126 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2128 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2131 if (close (pipe_fd
[1]) < 0)
2132 fatal_perror ("close %d", pipe_fd
[1]);
2135 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2137 /* Read each line of nm output. */
2138 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2143 /* If it contains a constructor or destructor name, add the name
2144 to the appropriate list. */
2146 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2147 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2154 /* Find the end of the symbol name.
2155 Do not include `|', because Encore nm can tack that on the end. */
2156 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2162 switch (is_ctor_dtor (name
))
2165 if (which_pass
!= PASS_LIB
)
2166 add_to_list (&constructors
, name
);
2170 if (which_pass
!= PASS_LIB
)
2171 add_to_list (&destructors
, name
);
2175 if (which_pass
!= PASS_LIB
)
2176 fatal ("init function found in object %s", prog_name
);
2177 #ifndef LD_INIT_SWITCH
2178 add_to_list (&constructors
, name
);
2183 if (which_pass
!= PASS_LIB
)
2184 fatal ("fini function found in object %s", prog_name
);
2185 #ifndef LD_FINI_SWITCH
2186 add_to_list (&destructors
, name
);
2191 if (which_pass
!= PASS_LIB
)
2192 add_to_list (&frame_tables
, name
);
2195 default: /* not a constructor or destructor */
2200 fprintf (stderr
, "\t%s\n", buf
);
2204 fprintf (stderr
, "\n");
2206 if (fclose (inf
) != 0)
2207 fatal_perror ("fclose");
2209 do_wait (nm_file_name
);
2211 signal (SIGINT
, int_handler
);
2213 signal (SIGQUIT
, quit_handler
);
2217 #if SUNOS4_SHARED_LIBRARIES
2219 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2220 that the output file depends upon and their initialization/finalization
2221 routines, if any. */
2226 #include <sys/mman.h>
2227 #include <sys/param.h>
2229 #include <sys/dir.h>
2231 /* pointers to the object file */
2232 unsigned object
; /* address of memory mapped file */
2233 unsigned objsize
; /* size of memory mapped to file */
2234 char * code
; /* pointer to code segment */
2235 char * data
; /* pointer to data segment */
2236 struct nlist
*symtab
; /* pointer to symbol table */
2237 struct link_dynamic
*ld
;
2238 struct link_dynamic_2
*ld_2
;
2239 struct head libraries
;
2241 /* Map the file indicated by NAME into memory and store its address. */
2243 static void mapfile
PARAMS ((const char *));
2251 if ((fp
= open (name
, O_RDONLY
)) == -1)
2252 fatal ("unable to open file '%s'", name
);
2253 if (fstat (fp
, &s
) == -1)
2254 fatal ("unable to stat file '%s'", name
);
2256 objsize
= s
.st_size
;
2257 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2259 if (object
== (unsigned)-1)
2260 fatal ("unable to mmap file '%s'", name
);
2265 /* Helpers for locatelib. */
2267 static const char *libname
;
2269 static int libselect
PARAMS ((struct direct
*));
2275 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2278 /* If one file has an additional numeric extension past LIBNAME, then put
2279 that one first in the sort. If both files have additional numeric
2280 extensions, then put the one with the higher number first in the sort.
2282 We must verify that the extension is numeric, because Sun saves the
2283 original versions of patched libraries with a .FCS extension. Files with
2284 invalid extensions must go last in the sort, so that they will not be used. */
2285 static int libcompare
PARAMS ((struct direct
**, struct direct
**));
2289 struct direct
**d1
, **d2
;
2291 int i1
, i2
= strlen (libname
);
2292 char *e1
= (*d1
)->d_name
+ i2
;
2293 char *e2
= (*d2
)->d_name
+ i2
;
2295 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2296 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2300 i1
= strtol (e1
, &e1
, 10);
2301 i2
= strtol (e2
, &e2
, 10);
2308 /* It has a valid numeric extension, prefer this one. */
2309 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2311 /* It has an invalid numeric extension, must prefer the other one. */
2317 /* It has a valid numeric extension, prefer this one. */
2318 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2320 /* It has an invalid numeric extension, must prefer the other one. */
2328 /* Given the name NAME of a dynamic dependency, find its pathname and add
2329 it to the list of libraries. */
2330 static void locatelib
PARAMS ((const char *));
2336 static const char **l
;
2338 char buf
[MAXPATHLEN
];
2346 /* counting elements in array, need 1 extra for null */
2348 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2352 for (; *ld_rules
!= 0; ld_rules
++)
2353 if (*ld_rules
== ':')
2355 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2356 ldr
= xstrdup (ld_rules
);
2358 p
= getenv ("LD_LIBRARY_PATH");
2363 for (q
= p
; *q
!= 0; q
++)
2368 l
= (const char **) xmalloc ((cnt
+ 3) * sizeof (char *));
2373 for (; *ldr
!= 0; ldr
++)
2383 for (; *q
!= 0; q
++)
2390 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2393 *pp
++ = "/usr/local/lib";
2397 for (pp
= l
; *pp
!= 0 ; pp
++)
2399 struct direct
**namelist
;
2401 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2403 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2404 add_to_list (&libraries
, buf
);
2406 fprintf (stderr
, "%s\n", buf
);
2413 notice ("not found\n");
2415 fatal ("dynamic dependency %s not found", name
);
2419 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2420 that it depends upon and any constructors or destructors they contain. */
2423 scan_libraries (prog_name
)
2424 const char *prog_name
;
2426 struct exec
*header
;
2428 struct link_object
*lo
;
2429 char buff
[MAXPATHLEN
];
2432 mapfile (prog_name
);
2433 header
= (struct exec
*)object
;
2434 if (N_BADMAG (*header
))
2435 fatal ("bad magic number in file '%s'", prog_name
);
2436 if (header
->a_dynamic
== 0)
2439 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2440 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2441 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2443 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2446 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2452 ld
= (struct link_dynamic
*) data
;
2457 notice ("dynamic dependencies.\n");
2459 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2460 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2461 lo
= (struct link_object
*) lo
->lo_next
)
2464 lo
= (struct link_object
*) ((long) lo
+ code
);
2465 name
= (char *) (code
+ lo
->lo_name
);
2469 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2470 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2476 fprintf (stderr
, "\t%s\n", name
);
2477 add_to_list (&libraries
, name
);
2482 fprintf (stderr
, "\n");
2484 /* now iterate through the library list adding their symbols to
2486 for (list
= libraries
.first
; list
; list
= list
->next
)
2487 scan_prog_file (list
->name
, PASS_LIB
);
2490 #else /* SUNOS4_SHARED_LIBRARIES */
2493 /* Use the List Dynamic Dependencies program to find shared libraries that
2494 the output file depends upon and their initialization/finalization
2495 routines, if any. */
2498 scan_libraries (prog_name
)
2499 const char *prog_name
;
2501 static struct head libraries
; /* list of shared libraries found */
2503 void (*int_handler
) PARAMS ((int));
2504 void (*quit_handler
) PARAMS ((int));
2505 char *real_ldd_argv
[4];
2506 const char **ldd_argv
= (const char **) real_ldd_argv
;
2512 /* If we do not have an `ldd', complain. */
2513 if (ldd_file_name
== 0)
2515 error ("cannot find `ldd'");
2519 ldd_argv
[argc
++] = ldd_file_name
;
2520 ldd_argv
[argc
++] = prog_name
;
2521 ldd_argv
[argc
++] = (char *) 0;
2523 if (pipe (pipe_fd
) < 0)
2524 fatal_perror ("pipe");
2526 inf
= fdopen (pipe_fd
[0], "r");
2527 if (inf
== (FILE *) 0)
2528 fatal_perror ("fdopen");
2530 /* Trace if needed. */
2533 const char **p_argv
;
2536 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2537 fprintf (stderr
, " %s", str
);
2539 fprintf (stderr
, "\n");
2545 /* Spawn child ldd on pipe */
2548 fatal_perror (VFORK_STRING
);
2550 if (pid
== 0) /* child context */
2553 if (dup2 (pipe_fd
[1], 1) < 0)
2554 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2556 if (close (pipe_fd
[0]) < 0)
2557 fatal_perror ("close %d", pipe_fd
[0]);
2559 if (close (pipe_fd
[1]) < 0)
2560 fatal_perror ("close %d", pipe_fd
[1]);
2562 execv (ldd_file_name
, real_ldd_argv
);
2563 fatal_perror ("execv %s", ldd_file_name
);
2566 /* Parent context from here on. */
2567 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2569 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2572 if (close (pipe_fd
[1]) < 0)
2573 fatal_perror ("close %d", pipe_fd
[1]);
2576 notice ("\nldd output with constructors/destructors.\n");
2578 /* Read each line of ldd output. */
2579 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2582 char *name
, *end
, *p
= buf
;
2584 /* Extract names of libraries and add to list. */
2585 PARSE_LDD_OUTPUT (p
);
2590 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2591 fatal ("dynamic dependency %s not found", buf
);
2593 /* Find the end of the symbol name. */
2595 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2600 if (access (name
, R_OK
) == 0)
2601 add_to_list (&libraries
, name
);
2603 fatal ("unable to open dynamic dependency '%s'", buf
);
2606 fprintf (stderr
, "\t%s\n", buf
);
2609 fprintf (stderr
, "\n");
2611 if (fclose (inf
) != 0)
2612 fatal_perror ("fclose");
2614 do_wait (ldd_file_name
);
2616 signal (SIGINT
, int_handler
);
2618 signal (SIGQUIT
, quit_handler
);
2621 /* now iterate through the library list adding their symbols to
2623 for (list
= libraries
.first
; list
; list
= list
->next
)
2624 scan_prog_file (list
->name
, PASS_LIB
);
2627 #endif /* LDD_SUFFIX */
2628 #endif /* SUNOS4_SHARED_LIBRARIES */
2630 #endif /* OBJECT_FORMAT_NONE */
2634 * COFF specific stuff.
2637 #ifdef OBJECT_FORMAT_COFF
2639 #if defined(EXTENDED_COFF)
2641 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2642 # define GCC_SYMENT SYMR
2643 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2644 # define GCC_SYMINC(X) (1)
2645 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2646 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2650 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2651 # define GCC_SYMENT SYMENT
2652 # define GCC_OK_SYMBOL(X) \
2653 (((X).n_sclass == C_EXT) && \
2654 ((X).n_scnum > N_UNDEF) && \
2656 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2657 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2658 # define GCC_UNDEF_SYMBOL(X) \
2659 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2660 # define GCC_SYMINC(X) ((X).n_numaux+1)
2661 # define GCC_SYMZERO(X) 0
2663 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2665 # define GCC_CHECK_HDR(X) \
2666 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2667 || (HEADER (X).f_magic == 0767 && aix64_flag))
2669 # define GCC_CHECK_HDR(X) \
2670 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2671 || (HEADER (X).f_magic == 0757 && aix64_flag))
2676 #ifdef COLLECT_EXPORT_LIST
2677 /* Array of standard AIX libraries which should not
2678 be scanned for ctors/dtors. */
2679 static const char *const aix_std_libs
[] = {
2687 "/usr/lib/libc_r.a",
2688 "/usr/lib/libm_r.a",
2689 "/usr/lib/threads/libc.a",
2690 "/usr/ccs/lib/libc.a",
2691 "/usr/ccs/lib/libm.a",
2692 "/usr/ccs/lib/libc_r.a",
2693 "/usr/ccs/lib/libm_r.a",
2697 /* This function checks the filename and returns 1
2698 if this name matches the location of a standard AIX library. */
2699 static int ignore_library
PARAMS ((const char *));
2701 ignore_library (name
)
2704 const char *const *p
= &aix_std_libs
[0];
2705 while (*p
++ != NULL
)
2706 if (! strcmp (name
, *p
)) return 1;
2709 #endif /* COLLECT_EXPORT_LIST */
2711 #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2712 extern char *ldgetname
PARAMS ((LDFILE
*, GCC_SYMENT
*));
2715 /* COFF version to scan the name list of the loaded program for
2716 the symbols g++ uses for static constructors and destructors.
2718 The constructor table begins at __CTOR_LIST__ and contains a count
2719 of the number of pointers (or -1 if the constructors are built in a
2720 separate section by the linker), followed by the pointers to the
2721 constructor functions, terminated with a null pointer. The
2722 destructor table has the same format, and begins at __DTOR_LIST__. */
2725 scan_prog_file (prog_name
, which_pass
)
2726 const char *prog_name
;
2727 enum pass which_pass
;
2729 LDFILE
*ldptr
= NULL
;
2730 int sym_index
, sym_count
;
2733 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2736 #ifdef COLLECT_EXPORT_LIST
2737 /* We do not need scanning for some standard C libraries. */
2738 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2741 /* On AIX we have a loop, because there is not much difference
2742 between an object and an archive. This trick allows us to
2743 eliminate scan_libraries() function. */
2747 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2748 non-const char * filename parameter, even though it will not
2749 modify that string. So we must cast away const-ness here,
2750 which will cause -Wcast-qual to burp. */
2751 if ((ldptr
= ldopen ((char *)prog_name
, ldptr
)) != NULL
)
2753 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2754 fatal ("%s: not a COFF file", prog_name
);
2756 if (GCC_CHECK_HDR (ldptr
))
2758 sym_count
= GCC_SYMBOLS (ldptr
);
2759 sym_index
= GCC_SYMZERO (ldptr
);
2761 #ifdef COLLECT_EXPORT_LIST
2762 /* Is current archive member a shared object? */
2763 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2766 while (sym_index
< sym_count
)
2770 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2772 sym_index
+= GCC_SYMINC (symbol
);
2774 if (GCC_OK_SYMBOL (symbol
))
2778 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2779 continue; /* should never happen */
2781 #ifdef XCOFF_DEBUGGING_INFO
2782 /* All AIX function names have a duplicate entry
2783 beginning with a dot. */
2788 switch (is_ctor_dtor (name
))
2792 add_to_list (&constructors
, name
);
2793 #ifdef COLLECT_EXPORT_LIST
2794 if (which_pass
== PASS_OBJ
)
2795 add_to_list (&exports
, name
);
2801 add_to_list (&destructors
, name
);
2802 #ifdef COLLECT_EXPORT_LIST
2803 if (which_pass
== PASS_OBJ
)
2804 add_to_list (&exports
, name
);
2808 #ifdef COLLECT_EXPORT_LIST
2810 #ifndef LD_INIT_SWITCH
2812 add_to_list (&constructors
, name
);
2817 #ifndef LD_INIT_SWITCH
2819 add_to_list (&destructors
, name
);
2826 add_to_list (&frame_tables
, name
);
2827 #ifdef COLLECT_EXPORT_LIST
2828 if (which_pass
== PASS_OBJ
)
2829 add_to_list (&exports
, name
);
2833 default: /* not a constructor or destructor */
2834 #ifdef COLLECT_EXPORT_LIST
2835 /* If we are building a shared object on AIX we need
2836 to explicitly export all global symbols. */
2839 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2840 add_to_list (&exports
, name
);
2847 #if !defined(EXTENDED_COFF)
2848 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2849 symbol
.n_scnum
, symbol
.n_sclass
,
2850 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2854 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2855 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2860 #ifdef COLLECT_EXPORT_LIST
2863 /* If archive contains both 32-bit and 64-bit objects,
2864 we want to skip objects in other mode so mismatch normal. */
2866 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2867 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2873 fatal ("%s: cannot open as COFF file", prog_name
);
2875 #ifdef COLLECT_EXPORT_LIST
2876 /* On AIX loop continues while there are more members in archive. */
2878 while (ldclose (ldptr
) == FAILURE
);
2880 /* Otherwise we simply close ldptr. */
2881 (void) ldclose(ldptr
);
2884 #endif /* OBJECT_FORMAT_COFF */
2886 #ifdef COLLECT_EXPORT_LIST
2887 /* Given a library name without "lib" prefix, this function
2888 returns a full library name including a path. */
2890 resolve_lib_name (name
)
2896 for (i
= 0; libpaths
[i
]; i
++)
2897 if (libpaths
[i
]->max_len
> l
)
2898 l
= libpaths
[i
]->max_len
;
2900 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2902 for (i
= 0; libpaths
[i
]; i
++)
2904 struct prefix_list
*list
= libpaths
[i
]->plist
;
2905 for (; list
; list
= list
->next
)
2907 /* The following lines are needed because path_prefix list
2908 may contain directories both with trailing '/' and
2911 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
2913 for (j
= 0; libexts
[j
]; j
++)
2915 sprintf (lib_buf
, "%s%slib%s.%s",
2916 list
->prefix
, p
, name
, libexts
[j
]);
2917 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
2918 if (file_exists (lib_buf
))
2920 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
2927 fprintf (stderr
, "not found\n");
2929 fatal ("library lib%s not found", name
);
2932 #endif /* COLLECT_EXPORT_LIST */
2936 * OSF/rose specific stuff.
2939 #ifdef OBJECT_FORMAT_ROSE
2941 /* Union of the various load commands */
2943 typedef union load_union
2945 ldc_header_t hdr
; /* common header */
2946 load_cmd_map_command_t map
; /* map indexing other load cmds */
2947 interpreter_command_t iprtr
; /* interpreter pathname */
2948 strings_command_t str
; /* load commands strings section */
2949 region_command_t region
; /* region load command */
2950 reloc_command_t reloc
; /* relocation section */
2951 package_command_t pkg
; /* package load command */
2952 symbols_command_t sym
; /* symbol sections */
2953 entry_command_t ent
; /* program start section */
2954 gen_info_command_t info
; /* object information */
2955 func_table_command_t func
; /* function constructors/destructors */
2958 /* Structure to point to load command and data section in memory. */
2960 typedef struct load_all
2962 load_union_t
*load
; /* load command */
2963 char *section
; /* pointer to section */
2966 /* Structure to contain information about a file mapped into memory. */
2970 char *start
; /* start of map */
2971 char *name
; /* filename */
2972 long size
; /* size of the file */
2973 long rounded_size
; /* size rounded to page boundary */
2974 int fd
; /* file descriptor */
2975 int rw
; /* != 0 if opened read/write */
2976 int use_mmap
; /* != 0 if mmap'ed */
2979 extern int decode_mach_o_hdr ();
2980 extern int encode_mach_o_hdr ();
2982 static void add_func_table
PARAMS ((mo_header_t
*, load_all_t
*,
2983 symbol_info_t
*, int));
2984 static void print_header
PARAMS ((mo_header_t
*));
2985 static void print_load_command
PARAMS ((load_union_t
*, size_t, int));
2986 static void bad_header
PARAMS ((int));
2987 static struct file_info
*read_file
PARAMS ((const char *, int, int));
2988 static void end_file
PARAMS ((struct file_info
*));
2990 /* OSF/rose specific version to scan the name list of the loaded
2991 program for the symbols g++ uses for static constructors and
2994 The constructor table begins at __CTOR_LIST__ and contains a count
2995 of the number of pointers (or -1 if the constructors are built in a
2996 separate section by the linker), followed by the pointers to the
2997 constructor functions, terminated with a null pointer. The
2998 destructor table has the same format, and begins at __DTOR_LIST__. */
3001 scan_prog_file (prog_name
, which_pass
)
3002 const char *prog_name
;
3003 enum pass which_pass
;
3007 load_all_t
*load_array
;
3008 load_all_t
*load_end
;
3009 load_all_t
*load_cmd
;
3010 int symbol_load_cmds
;
3016 struct file_info
*obj_file
;
3018 mo_lcid_t cmd_strings
= -1;
3019 symbol_info_t
*main_sym
= 0;
3020 int rw
= (which_pass
!= PASS_FIRST
);
3022 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3024 fatal_perror ("open %s", prog_name
);
3026 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3027 obj
= obj_file
->start
;
3029 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3030 if (status
!= MO_HDR_CONV_SUCCESS
)
3031 bad_header (status
);
3034 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3035 since the hardware will automatically swap bytes for us on loading little endian
3038 #ifndef CROSS_COMPILE
3039 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3040 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3041 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3042 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3043 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3044 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3045 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3047 fatal ("incompatibilities between object file & expected values");
3052 print_header (&hdr
);
3054 offset
= hdr
.moh_first_cmd_off
;
3055 load_end
= load_array
3056 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3058 /* Build array of load commands, calculating the offsets */
3059 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3061 load_union_t
*load_hdr
; /* load command header */
3063 load_cmd
= load_end
++;
3064 load_hdr
= (load_union_t
*) (obj
+ offset
);
3066 /* If modifying the program file, copy the header. */
3069 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3070 memcpy ((char *)ptr
, (char *)load_hdr
, load_hdr
->hdr
.ldci_cmd_size
);
3073 /* null out old command map, because we will rewrite at the end. */
3074 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3076 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3077 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3081 load_cmd
->load
= load_hdr
;
3082 if (load_hdr
->hdr
.ldci_section_off
> 0)
3083 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3086 print_load_command (load_hdr
, offset
, i
);
3088 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3091 /* If the last command is the load command map and is not undefined,
3092 decrement the count of load commands. */
3093 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3096 hdr
.moh_n_load_cmds
--;
3099 /* Go through and process each symbol table section. */
3100 symbol_load_cmds
= 0;
3101 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3103 load_union_t
*load_hdr
= load_cmd
->load
;
3105 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3111 const char *kind
= "unknown";
3113 switch (load_hdr
->sym
.symc_kind
)
3115 case SYMC_IMPORTS
: kind
= "imports"; break;
3116 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3117 case SYMC_STABS
: kind
= "stabs"; break;
3120 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3121 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3124 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3127 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3128 if (str_sect
== (char *) 0)
3129 fatal ("string section missing");
3131 if (load_cmd
->section
== (char *) 0)
3132 fatal ("section pointer missing");
3134 num_syms
= load_hdr
->sym
.symc_nentries
;
3135 for (i
= 0; i
< num_syms
; i
++)
3137 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3138 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3145 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3147 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3157 switch (is_ctor_dtor (name
))
3160 add_to_list (&constructors
, name
);
3164 add_to_list (&destructors
, name
);
3167 default: /* not a constructor or destructor */
3173 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3174 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3179 if (symbol_load_cmds
== 0)
3180 fatal ("no symbol table found");
3182 /* Update the program file now, rewrite header and load commands. At present,
3183 we assume that there is enough space after the last load command to insert
3184 one more. Since the first section written out is page aligned, and the
3185 number of load commands is small, this is ok for the present. */
3189 load_union_t
*load_map
;
3192 if (cmd_strings
== -1)
3193 fatal ("no cmd_strings found");
3195 /* Add __main to initializer list.
3196 If we are building a program instead of a shared library, do not
3197 do anything, since in the current version, you cannot do mallocs
3198 and such in the constructors. */
3200 if (main_sym
!= (symbol_info_t
*) 0
3201 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3202 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3205 notice ("\nUpdating header and load commands.\n\n");
3207 hdr
.moh_n_load_cmds
++;
3208 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3210 /* Create new load command map. */
3212 notice ("load command map, %d cmds, new size %ld.\n",
3213 (int) hdr
.moh_n_load_cmds
, (long) size
);
3215 load_map
= (load_union_t
*) xcalloc (1, size
);
3216 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3217 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3218 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3219 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3220 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3222 offset
= hdr
.moh_first_cmd_off
;
3223 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3225 load_map
->map
.lcm_map
[i
] = offset
;
3226 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3227 hdr
.moh_load_map_cmd_off
= offset
;
3229 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3232 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3235 print_header (&hdr
);
3238 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3239 if (status
!= MO_HDR_CONV_SUCCESS
)
3240 bad_header (status
);
3243 notice ("writing load commands.\n\n");
3245 /* Write load commands */
3246 offset
= hdr
.moh_first_cmd_off
;
3247 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3249 load_union_t
*load_hdr
= load_array
[i
].load
;
3250 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3253 print_load_command (load_hdr
, offset
, i
);
3255 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3260 end_file (obj_file
);
3262 if (close (prog_fd
))
3263 fatal_perror ("close %s", prog_name
);
3266 fprintf (stderr
, "\n");
3270 /* Add a function table to the load commands to call a function
3271 on initiation or termination of the process. */
3274 add_func_table (hdr_p
, load_array
, sym
, type
)
3275 mo_header_t
*hdr_p
; /* pointer to global header */
3276 load_all_t
*load_array
; /* array of ptrs to load cmds */
3277 symbol_info_t
*sym
; /* pointer to symbol entry */
3278 int type
; /* fntc_type value */
3280 /* Add a new load command. */
3281 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3282 int load_index
= num_cmds
- 1;
3283 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3284 load_union_t
*ptr
= xcalloc (1, size
);
3285 load_all_t
*load_cmd
;
3288 /* Set the unresolved address bit in the header to force the loader to be
3289 used, since kernel exec does not call the initialization functions. */
3290 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3292 load_cmd
= &load_array
[load_index
];
3293 load_cmd
->load
= ptr
;
3294 load_cmd
->section
= (char *) 0;
3296 /* Fill in func table load command. */
3297 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3298 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3299 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3300 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3301 ptr
->func
.fntc_type
= type
;
3302 ptr
->func
.fntc_nentries
= 1;
3304 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3305 /* Is the symbol already expressed as (region, offset)? */
3306 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3308 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3309 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3312 /* If not, figure out which region it's in. */
3315 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3318 for (i
= 0; i
< load_index
; i
++)
3320 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3322 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3324 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3325 && addr
>= region_ptr
->regc_addr
.vm_addr
3326 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3328 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3329 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3337 fatal ("could not convert 0x%l.8x into a region", addr
);
3341 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3342 type
== FNTC_INITIALIZATION
? "init" : "term",
3343 (int) ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3344 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3345 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3350 /* Print the global header for an OSF/rose object. */
3353 print_header (hdr_ptr
)
3354 mo_header_t
*hdr_ptr
;
3356 fprintf (stderr
, "\nglobal header:\n");
3357 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3358 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3359 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3360 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3361 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3362 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3363 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3364 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3365 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3366 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3367 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3368 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3369 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3370 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3371 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3373 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3374 fprintf (stderr
, ", relocatable");
3376 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3377 fprintf (stderr
, ", linkable");
3379 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3380 fprintf (stderr
, ", execable");
3382 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3383 fprintf (stderr
, ", executable");
3385 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3386 fprintf (stderr
, ", unresolved");
3388 fprintf (stderr
, "\n\n");
3393 /* Print a short summary of a load command. */
3396 print_load_command (load_hdr
, offset
, number
)
3397 load_union_t
*load_hdr
;
3401 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3402 const char *type_str
= (char *) 0;
3406 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3407 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3408 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3409 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3410 case LDC_REGION
: type_str
= "REGION"; break;
3411 case LDC_RELOC
: type_str
= "RELOC"; break;
3412 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3413 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3414 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3415 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3416 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3420 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3422 (long) load_hdr
->hdr
.ldci_cmd_size
,
3424 (long) load_hdr
->hdr
.ldci_section_off
,
3425 (long) load_hdr
->hdr
.ldci_section_len
);
3427 if (type_str
== (char *) 0)
3428 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3430 else if (type
!= LDC_REGION
)
3431 fprintf (stderr
, ", ty: %s\n", type_str
);
3435 const char *region
= "";
3436 switch (load_hdr
->region
.regc_usage_type
)
3438 case REG_TEXT_T
: region
= ", .text"; break;
3439 case REG_DATA_T
: region
= ", .data"; break;
3440 case REG_BSS_T
: region
= ", .bss"; break;
3441 case REG_GLUE_T
: region
= ", .glue"; break;
3442 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3443 case REG_RDATA_T
: region
= ", .rdata"; break;
3444 case REG_SDATA_T
: region
= ", .sdata"; break;
3445 case REG_SBSS_T
: region
= ", .sbss"; break;
3449 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3451 (long) load_hdr
->region
.regc_vm_addr
,
3452 (long) load_hdr
->region
.regc_vm_size
,
3460 /* Fatal error when {en,de}code_mach_o_header fails. */
3468 case MO_ERROR_BAD_MAGIC
: fatal ("bad magic number");
3469 case MO_ERROR_BAD_HDR_VERS
: fatal ("bad header version");
3470 case MO_ERROR_BAD_RAW_HDR_VERS
: fatal ("bad raw header version");
3471 case MO_ERROR_BUF2SML
: fatal ("raw header buffer too small");
3472 case MO_ERROR_OLD_RAW_HDR_FILE
: fatal ("old raw header file");
3473 case MO_ERROR_UNSUPPORTED_VERS
: fatal ("unsupported version");
3475 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3480 /* Read a file into a memory buffer. */
3482 static struct file_info
*
3483 read_file (name
, fd
, rw
)
3484 const char *name
; /* filename */
3485 int fd
; /* file descriptor */
3486 int rw
; /* read/write */
3488 struct stat stat_pkt
;
3489 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3491 static int page_size
;
3494 if (fstat (fd
, &stat_pkt
) < 0)
3495 fatal_perror ("fstat %s", name
);
3498 p
->size
= stat_pkt
.st_size
;
3499 p
->rounded_size
= stat_pkt
.st_size
;
3505 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3508 page_size
= sysconf (_SC_PAGE_SIZE
);
3510 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3511 p
->start
= mmap ((caddr_t
) 0,
3512 (rw
) ? p
->rounded_size
: p
->size
,
3513 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3514 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3518 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3522 #endif /* USE_MMAP */
3527 fprintf (stderr
, "read %s\n", name
);
3530 p
->start
= xmalloc (p
->size
);
3531 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3532 fatal_perror ("lseek %s 0", name
);
3534 len
= read (fd
, p
->start
, p
->size
);
3536 fatal_perror ("read %s", name
);
3539 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3545 /* Do anything necessary to write a file back from memory. */
3549 struct file_info
*ptr
; /* file information block */
3557 fprintf (stderr
, "msync %s\n", ptr
->name
);
3559 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3560 fatal_perror ("msync %s", ptr
->name
);
3564 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3566 if (munmap (ptr
->start
, ptr
->size
))
3567 fatal_perror ("munmap %s", ptr
->name
);
3570 #endif /* USE_MMAP */
3577 fprintf (stderr
, "write %s\n", ptr
->name
);
3579 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3580 fatal_perror ("lseek %s 0", ptr
->name
);
3582 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3584 fatal_perror ("write %s", ptr
->name
);
3586 if (len
!= ptr
->size
)
3587 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3596 #endif /* OBJECT_FORMAT_ROSE */