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 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 GNU CC.
11 GNU CC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GNU CC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GNU CC; see the file COPYING. If not, write to
23 the Free Software Foundation, 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
33 #ifdef vfork /* Autoconf may define this to fork for us. */
34 # define VFORK_STRING "fork"
36 # define VFORK_STRING "vfork"
42 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
43 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
46 #ifndef LIBRARY_PATH_ENV
47 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
58 /* Obstack allocation and deallocation routines. */
59 #define obstack_chunk_alloc xmalloc
60 #define obstack_chunk_free free
62 /* On certain systems, we have code that works by scanning the object file
63 directly. But this code uses system-specific header files and library
64 functions, so turn it off in a cross-compiler. Likewise, the names of
65 the utilities are not correct for a cross-compiler; we have to hope that
66 cross-versions are in the proper directories. */
69 #undef SUNOS4_SHARED_LIBRARIES
70 #undef OBJECT_FORMAT_COFF
71 #undef OBJECT_FORMAT_ROSE
73 #undef REAL_LD_FILE_NAME
74 #undef REAL_NM_FILE_NAME
75 #undef REAL_STRIP_FILE_NAME
78 /* If we cannot use a special method, use the ordinary one:
79 run nm to find what symbols are present.
80 In a cross-compiler, this means you need a cross nm,
81 but that is not quite as unpleasant as special headers. */
83 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
84 #define OBJECT_FORMAT_NONE
87 #ifdef OBJECT_FORMAT_COFF
96 /* Many versions of ldfcn.h define these. */
104 /* Some systems have an ISCOFF macro, but others do not. In some cases
105 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
106 that either do not have an ISCOFF macro in /usr/include or for those
107 where it is wrong. */
110 #define MY_ISCOFF(X) ISCOFF (X)
113 #endif /* OBJECT_FORMAT_COFF */
115 #ifdef OBJECT_FORMAT_ROSE
122 #include <sys/mman.h>
126 #include <mach_o_format.h>
127 #include <mach_o_header.h>
128 #include <mach_o_vals.h>
129 #include <mach_o_types.h>
131 #endif /* OBJECT_FORMAT_ROSE */
133 #ifdef OBJECT_FORMAT_NONE
135 /* Default flags to pass to nm. */
137 #define NM_FLAGS "-n"
140 #endif /* OBJECT_FORMAT_NONE */
142 /* Some systems use __main in a way incompatible with its use in gcc, in these
143 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
144 give the same symbol without quotes for an alternative entry point. You
145 must define both, or neither. */
147 #define NAME__MAIN "__main"
148 #define SYMBOL__MAIN __main
151 /* This must match tree.h. */
152 #define DEFAULT_INIT_PRIORITY 65535
154 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
155 #define SCAN_LIBRARIES
159 int do_collecting
= 1;
161 int do_collecting
= 0;
164 /* Linked lists of constructor and destructor names. */
180 /* Enumeration giving which pass this is for scanning the program file. */
183 PASS_FIRST
, /* without constructors */
184 PASS_OBJ
, /* individual objects */
185 PASS_LIB
, /* looking for shared libraries */
186 PASS_SECOND
/* with constructors linked in */
189 int vflag
; /* true if -v */
190 static int rflag
; /* true if -r */
191 static int strip_flag
; /* true if -s */
192 #ifdef COLLECT_EXPORT_LIST
193 static int export_flag
; /* true if -bE */
194 static int aix64_flag
; /* true if -b64 */
197 int debug
; /* true if -debug */
199 static int shared_obj
; /* true if -shared */
201 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
202 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
203 #ifdef COLLECT_EXPORT_LIST
204 static const char *export_file
; /* <xxx>.x for AIX export list. */
205 static const char *import_file
; /* <xxx>.p for AIX import list. */
207 const char *ldout
; /* File for ld errors. */
208 static const char *output_file
; /* Output file for ld. */
209 static const char *nm_file_name
; /* pathname of nm */
211 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
213 static const char *strip_file_name
; /* pathname of strip */
214 const char *c_file_name
; /* pathname of gcc */
215 static char *initname
, *fininame
; /* names of init and fini funcs */
217 static struct head constructors
; /* list of constructors found */
218 static struct head destructors
; /* list of destructors found */
219 #ifdef COLLECT_EXPORT_LIST
220 static struct head exports
; /* list of exported symbols */
221 static struct head imports
; /* list of imported symbols */
222 static struct head undefined
; /* list of undefined symbols */
224 static struct head frame_tables
; /* list of frame unwind info tables */
226 struct obstack temporary_obstack
;
227 struct obstack permanent_obstack
;
228 char * temporary_firstobj
;
230 /* Holds the return value of pexecute. */
233 /* Defined in the automatically-generated underscore.c. */
234 extern int prepends_underscore
;
236 #ifndef GET_ENV_PATH_LIST
237 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
240 /* Structure to hold all the directories in which to search for files to
245 const char *prefix
; /* String to prepend to the path. */
246 struct prefix_list
*next
; /* Next in linked list. */
251 struct prefix_list
*plist
; /* List of prefixes to try */
252 int max_len
; /* Max length of a prefix in PLIST */
253 const char *name
; /* Name of this list (used in config stuff) */
256 #ifdef COLLECT_EXPORT_LIST
257 /* Lists to keep libraries to be scanned for global constructors/destructors. */
258 static struct head libs
; /* list of libraries */
259 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
260 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
261 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
262 &libpath_lib_dirs
, NULL
};
263 static const char *libexts
[3] = {"a", "so", NULL
}; /* possible library extentions */
266 static void handler
PARAMS ((int));
267 static int is_ctor_dtor
PARAMS ((const char *));
268 static char *find_a_file
PARAMS ((struct path_prefix
*, const char *));
269 static void add_prefix
PARAMS ((struct path_prefix
*, const char *));
270 static void prefix_from_env
PARAMS ((const char *, struct path_prefix
*));
271 static void prefix_from_string
PARAMS ((const char *, struct path_prefix
*));
272 static void do_wait
PARAMS ((const char *));
273 static void fork_execute
PARAMS ((const char *, char **));
274 static void maybe_unlink
PARAMS ((const char *));
275 static void add_to_list
PARAMS ((struct head
*, const char *));
276 static int extract_init_priority
PARAMS ((const char *));
277 static void sort_ids
PARAMS ((struct head
*));
278 static void write_list
PARAMS ((FILE *, const char *, struct id
*));
279 #ifdef COLLECT_EXPORT_LIST
280 static void dump_list
PARAMS ((FILE *, const char *, struct id
*));
283 static void dump_prefix_list
PARAMS ((FILE *, const char *, struct prefix_list
*));
285 static void write_list_with_asm
PARAMS ((FILE *, const char *, struct id
*));
286 static void write_c_file
PARAMS ((FILE *, const char *));
287 static void write_c_file_stat
PARAMS ((FILE *, const char *));
288 #ifndef LD_INIT_SWITCH
289 static void write_c_file_glob
PARAMS ((FILE *, const char *));
291 static void scan_prog_file
PARAMS ((const char *, enum pass
));
292 #ifdef SCAN_LIBRARIES
293 static void scan_libraries
PARAMS ((const char *));
295 #ifdef COLLECT_EXPORT_LIST
296 static int is_in_list
PARAMS ((const char *, struct id
*));
297 static void write_aix_file
PARAMS ((FILE *, struct id
*));
298 static char *resolve_lib_name
PARAMS ((const char *));
299 static int use_import_list
PARAMS ((const char *));
300 static int ignore_library
PARAMS ((const char *));
302 static char *extract_string
PARAMS ((const char **));
317 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
320 close (fdtmp
[--fdx
]);
326 /* Delete tempfiles and exit function. */
329 collect_exit (status
)
332 if (c_file
!= 0 && c_file
[0])
333 maybe_unlink (c_file
);
335 if (o_file
!= 0 && o_file
[0])
336 maybe_unlink (o_file
);
338 #ifdef COLLECT_EXPORT_LIST
339 if (export_file
!= 0 && export_file
[0])
340 maybe_unlink (export_file
);
342 if (import_file
!= 0 && import_file
[0])
343 maybe_unlink (import_file
);
346 if (ldout
!= 0 && ldout
[0])
349 maybe_unlink (ldout
);
352 if (status
!= 0 && output_file
!= 0 && output_file
[0])
353 maybe_unlink (output_file
);
359 /* Notify user of a non-error. */
361 notice
VPARAMS ((const char *msgid
, ...))
363 #ifndef ANSI_PROTOTYPES
368 VA_START (ap
, msgid
);
370 #ifndef ANSI_PROTOTYPES
371 msgid
= va_arg (ap
, const char *);
374 vfprintf (stderr
, _(msgid
), ap
);
378 /* Die when sys call fails. */
381 fatal_perror
VPARAMS ((const char * msgid
, ...))
383 #ifndef ANSI_PROTOTYPES
389 VA_START (ap
, msgid
);
391 #ifndef ANSI_PROTOTYPES
392 msgid
= va_arg (ap
, const char *);
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
, ...))
408 #ifndef ANSI_PROTOTYPES
413 VA_START (ap
, msgid
);
415 #ifndef ANSI_PROTOTYPES
416 msgid
= va_arg (ap
, const char *);
419 fprintf (stderr
, "collect2: ");
420 vfprintf (stderr
, _(msgid
), ap
);
421 fprintf (stderr
, "\n");
424 collect_exit (FATAL_EXIT_CODE
);
427 /* Write error message. */
430 error
VPARAMS ((const char * msgid
, ...))
432 #ifndef ANSI_PROTOTYPES
437 VA_START (ap
, msgid
);
439 #ifndef ANSI_PROTOTYPES
440 msgid
= va_arg (ap
, const char *);
443 fprintf (stderr
, "collect2: ");
444 vfprintf (stderr
, _(msgid
), ap
);
445 fprintf (stderr
, "\n");
449 /* In case obstack is linked in, and abort is defined to fancy_abort,
450 provide a default entry. */
455 fatal ("internal error");
462 if (c_file
!= 0 && c_file
[0])
463 maybe_unlink (c_file
);
465 if (o_file
!= 0 && o_file
[0])
466 maybe_unlink (o_file
);
468 if (ldout
!= 0 && ldout
[0])
469 maybe_unlink (ldout
);
471 #ifdef COLLECT_EXPORT_LIST
472 if (export_file
!= 0 && export_file
[0])
473 maybe_unlink (export_file
);
475 if (import_file
!= 0 && import_file
[0])
476 maybe_unlink (import_file
);
479 signal (signo
, SIG_DFL
);
480 kill (getpid (), signo
);
488 return access (name
, R_OK
) == 0;
491 /* Parse a reasonable subset of shell quoting syntax. */
508 obstack_1grow (&temporary_obstack
, c
);
509 else if (! inside
&& c
== ' ')
511 else if (! inside
&& c
== '\\')
516 obstack_1grow (&temporary_obstack
, c
);
519 obstack_1grow (&temporary_obstack
, '\0');
521 return obstack_finish (&temporary_obstack
);
528 FILE *stream
= fopen (name
, "r");
529 int no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
536 while (c
= getc (stream
),
537 c
!= EOF
&& (ISALNUM (c
) || c
== '_' || c
== '$' || c
== '.'))
538 obstack_1grow (&temporary_obstack
, c
);
539 if (obstack_object_size (&temporary_obstack
) > 0)
541 const char *word
, *p
;
543 obstack_1grow (&temporary_obstack
, '\0');
544 word
= obstack_finish (&temporary_obstack
);
547 ++word
, putc ('.', stderr
);
549 if (*p
== '_' && prepends_underscore
)
555 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
);
560 fputs (result
, stderr
);
562 diff
= strlen (word
) - strlen (result
);
564 --diff
, putc (' ', stderr
);
565 while (diff
< 0 && c
== ' ')
566 ++diff
, c
= getc (stream
);
571 fputs (word
, stderr
);
574 obstack_free (&temporary_obstack
, temporary_firstobj
);
583 /* Decide whether the given symbol is: a constructor (1), a destructor
584 (2), a routine in a shared object that calls all the constructors
585 (3) or destructors (4), a DWARF exception-handling table (5), or
586 nothing special (0). */
592 struct names
{ const char *name
; int len
; int ret
; int two_underscores
; };
594 register struct names
*p
;
596 register const char *orig_s
= s
;
598 static struct names special
[] = {
599 #ifdef NO_DOLLAR_IN_LABEL
600 #ifdef NO_DOT_IN_LABEL
601 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
602 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
603 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
605 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
606 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
607 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
610 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
611 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
612 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
614 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
615 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
616 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
617 cfront has its own linker procedure to collect them;
618 if collect2 gets them too, they get collected twice
619 when the cfront procedure is run and the compiler used
620 for linking happens to be GCC. */
621 { "sti__", sizeof ("sti__")-1, 1, 1 },
622 { "std__", sizeof ("std__")-1, 2, 1 },
623 #endif /* CFRONT_LOSSAGE */
627 while ((ch
= *s
) == '_')
633 for (p
= &special
[0]; p
->len
> 0; p
++)
636 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
637 && strncmp(s
, p
->name
, p
->len
) == 0)
645 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
646 and one from the PATH variable. */
648 static struct path_prefix cpath
, path
;
651 /* This is the name of the target machine. We use it to form the name
652 of the files to execute. */
654 static const char *const target_machine
= TARGET_MACHINE
;
657 /* Search for NAME using prefix list PPREFIX. We only look for executable
660 Return 0 if not found, otherwise return its name, allocated with malloc. */
663 find_a_file (pprefix
, name
)
664 struct path_prefix
*pprefix
;
668 struct prefix_list
*pl
;
669 int len
= pprefix
->max_len
+ strlen (name
) + 1;
672 fprintf (stderr
, "Looking for '%s'\n", name
);
674 #ifdef EXECUTABLE_SUFFIX
675 len
+= strlen (EXECUTABLE_SUFFIX
);
678 temp
= xmalloc (len
);
680 /* Determine the filename to execute (special case for absolute paths). */
683 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
684 || (*name
&& name
[1] == ':')
688 if (access (name
, X_OK
) == 0)
693 fprintf (stderr
, " - found: absolute path\n");
698 #ifdef EXECUTABLE_SUFFIX
699 /* Some systems have a suffix for executable files.
700 So try appending that. */
702 strcat (temp
, EXECUTABLE_SUFFIX
);
704 if (access (temp
, X_OK
) == 0)
709 fprintf (stderr
, " - failed to locate using absolute path\n");
712 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
716 strcpy (temp
, pl
->prefix
);
719 if (stat (temp
, &st
) >= 0
720 && ! S_ISDIR (st
.st_mode
)
721 && access (temp
, X_OK
) == 0)
724 #ifdef EXECUTABLE_SUFFIX
725 /* Some systems have a suffix for executable files.
726 So try appending that. */
727 strcat (temp
, EXECUTABLE_SUFFIX
);
729 if (stat (temp
, &st
) >= 0
730 && ! S_ISDIR (st
.st_mode
)
731 && access (temp
, X_OK
) == 0)
736 if (debug
&& pprefix
->plist
== NULL
)
737 fprintf (stderr
, " - failed: no entries in prefix list\n");
743 /* Add an entry for PREFIX to prefix list PPREFIX. */
746 add_prefix (pprefix
, prefix
)
747 struct path_prefix
*pprefix
;
750 struct prefix_list
*pl
, **prev
;
755 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
760 prev
= &pprefix
->plist
;
762 /* Keep track of the longest prefix */
764 len
= strlen (prefix
);
765 if (len
> pprefix
->max_len
)
766 pprefix
->max_len
= len
;
768 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
769 pl
->prefix
= xstrdup (prefix
);
774 pl
->next
= (struct prefix_list
*) 0;
778 /* Take the value of the environment variable ENV, break it into a path, and
779 add of the entries to PPREFIX. */
782 prefix_from_env (env
, pprefix
)
784 struct path_prefix
*pprefix
;
787 GET_ENV_PATH_LIST (p
, env
);
790 prefix_from_string (p
, pprefix
);
794 prefix_from_string (p
, pprefix
)
796 struct path_prefix
*pprefix
;
798 const char *startp
, *endp
;
799 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
802 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
807 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
809 strncpy (nstore
, startp
, endp
-startp
);
812 strcpy (nstore
, "./");
814 else if (! IS_DIR_SEPARATOR (endp
[-1]))
816 nstore
[endp
-startp
] = DIR_SEPARATOR
;
817 nstore
[endp
-startp
+1] = 0;
820 nstore
[endp
-startp
] = 0;
823 fprintf (stderr
, " - add prefix: %s\n", nstore
);
825 add_prefix (pprefix
, nstore
);
828 endp
= startp
= endp
+ 1;
837 int main
PARAMS ((int, char *[]));
843 const char *ld_suffix
= "ld";
844 const char *full_ld_suffix
= ld_suffix
;
845 const char *real_ld_suffix
= "real-ld";
846 const char *collect_ld_suffix
= "collect-ld";
847 const char *nm_suffix
= "nm";
848 const char *full_nm_suffix
= nm_suffix
;
849 const char *gnm_suffix
= "gnm";
850 const char *full_gnm_suffix
= gnm_suffix
;
852 const char *ldd_suffix
= LDD_SUFFIX
;
853 const char *full_ldd_suffix
= ldd_suffix
;
855 const char *strip_suffix
= "strip";
856 const char *full_strip_suffix
= strip_suffix
;
857 const char *gstrip_suffix
= "gstrip";
858 const char *full_gstrip_suffix
= gstrip_suffix
;
861 #ifdef COLLECT_EXPORT_LIST
865 const char *ld_file_name
;
876 int num_c_args
= argc
+9;
878 #if defined (COLLECT2_HOST_INITIALIZATION)
879 /* Perform system dependant initialization, if neccessary. */
880 COLLECT2_HOST_INITIALIZATION
;
883 #ifdef HAVE_LC_MESSAGES
884 setlocale (LC_MESSAGES
, "");
886 (void) bindtextdomain (PACKAGE
, localedir
);
887 (void) textdomain (PACKAGE
);
889 /* Do not invoke xcalloc before this point, since locale needs to be
890 set first, in case a diagnostic is issued. */
892 ld1
= (const char **)(ld1_argv
= (char **) xcalloc(sizeof (char *), argc
+3));
893 ld2
= (const char **)(ld2_argv
= (char **) xcalloc(sizeof (char *), argc
+10));
894 object
= (const char **)(object_lst
= (char **) xcalloc(sizeof (char *), argc
));
900 /* Parse command line early for instances of -debug. This allows
901 the debug flag to be set before functions like find_a_file()
906 for (i
= 1; argv
[i
] != NULL
; i
++)
907 if (! strcmp (argv
[i
], "-debug"))
912 #ifndef DEFAULT_A_OUT_NAME
913 output_file
= "a.out";
915 output_file
= DEFAULT_A_OUT_NAME
;
918 obstack_begin (&temporary_obstack
, 0);
919 obstack_begin (&permanent_obstack
, 0);
920 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
922 current_demangling_style
= gnu_demangling
;
923 p
= getenv ("COLLECT_GCC_OPTIONS");
926 const char *q
= extract_string (&p
);
927 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
930 obstack_free (&temporary_obstack
, temporary_firstobj
);
932 /* -fno-exceptions -w */
935 c_ptr
= (const char **)
936 (c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
));
939 fatal ("no arguments");
942 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
943 signal (SIGQUIT
, handler
);
945 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
946 signal (SIGINT
, handler
);
948 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
949 signal (SIGALRM
, handler
);
952 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
953 signal (SIGHUP
, handler
);
955 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
956 signal (SIGSEGV
, handler
);
958 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
959 signal (SIGBUS
, handler
);
962 /* Extract COMPILER_PATH and PATH into our prefix list. */
963 prefix_from_env ("COMPILER_PATH", &cpath
);
964 prefix_from_env ("PATH", &path
);
967 /* If we look for a program in the compiler directories, we just use
968 the short name, since these directories are already system-specific.
969 But it we look for a program in the system directories, we need to
970 qualify the program name with the target machine. */
972 full_ld_suffix
= concat(target_machine
, "-", ld_suffix
, NULL
);
975 full_gld_suffix
= concat (target_machine
, "-", gld_suffix
, NULL
);
978 full_nm_suffix
= concat (target_machine
, "-", nm_suffix
, NULL
);
980 full_gnm_suffix
= concat (target_machine
, "-", gnm_suffix
, NULL
);
983 full_ldd_suffix
= concat (target_machine
, "-", ldd_suffix
, NULL
);
986 full_strip_suffix
= concat (target_machine
, "-", strip_suffix
, NULL
);
988 full_gstrip_suffix
= concat (target_machine
, "-", gstrip_suffix
, NULL
);
989 #endif /* CROSS_COMPILE */
991 /* Try to discover a valid linker/nm/strip to use. */
993 /* Maybe we know the right file to use (if not cross). */
995 #ifdef DEFAULT_LINKER
996 if (access (DEFAULT_LINKER
, X_OK
) == 0)
997 ld_file_name
= DEFAULT_LINKER
;
998 if (ld_file_name
== 0)
1000 #ifdef REAL_LD_FILE_NAME
1001 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
1002 if (ld_file_name
== 0)
1004 /* Search the (target-specific) compiler dirs for ld'. */
1005 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
1006 /* Likewise for `collect-ld'. */
1007 if (ld_file_name
== 0)
1008 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
1009 /* Search the compiler directories for `ld'. We have protection against
1010 recursive calls in find_a_file. */
1011 if (ld_file_name
== 0)
1012 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
1013 /* Search the ordinary system bin directories
1014 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1015 if (ld_file_name
== 0)
1016 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
1018 #ifdef REAL_NM_FILE_NAME
1019 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
1020 if (nm_file_name
== 0)
1022 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
1023 if (nm_file_name
== 0)
1024 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
1025 if (nm_file_name
== 0)
1026 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
1027 if (nm_file_name
== 0)
1028 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
1031 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
1032 if (ldd_file_name
== 0)
1033 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
1036 #ifdef REAL_STRIP_FILE_NAME
1037 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1038 if (strip_file_name
== 0)
1040 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1041 if (strip_file_name
== 0)
1042 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1043 if (strip_file_name
== 0)
1044 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1045 if (strip_file_name
== 0)
1046 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1048 /* Determine the full path name of the C compiler to use. */
1049 c_file_name
= getenv ("COLLECT_GCC");
1050 if (c_file_name
== 0)
1052 #ifdef CROSS_COMPILE
1053 c_file_name
= concat (target_machine
, "-gcc", NULL
);
1055 c_file_name
= "gcc";
1059 p
= find_a_file (&cpath
, c_file_name
);
1061 /* Here it should be safe to use the system search path since we should have
1062 already qualified the name of the compiler when it is needed. */
1064 p
= find_a_file (&path
, c_file_name
);
1069 *ld1
++ = *ld2
++ = ld_file_name
;
1071 /* Make temp file names. */
1072 c_file
= make_temp_file (".c");
1073 o_file
= make_temp_file (".o");
1074 #ifdef COLLECT_EXPORT_LIST
1075 export_file
= make_temp_file (".x");
1076 import_file
= make_temp_file (".p");
1078 ldout
= make_temp_file (".ld");
1079 *c_ptr
++ = c_file_name
;
1086 #ifdef COLLECT_EXPORT_LIST
1087 /* Generate a list of directories from LIBPATH. */
1088 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1089 /* Add to this list also two standard directories where
1090 AIX loader always searches for libraries. */
1091 add_prefix (&libpath_lib_dirs
, "/lib");
1092 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1095 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1097 AIX support needs to know if -shared has been specified before
1098 parsing commandline arguments. */
1100 p
= getenv ("COLLECT_GCC_OPTIONS");
1103 const char *q
= extract_string (&p
);
1104 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1105 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1106 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1107 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1108 if (strncmp (q
, "-shared", sizeof ("-shared") - 1) == 0)
1111 obstack_free (&temporary_obstack
, temporary_firstobj
);
1112 *c_ptr
++ = "-fno-exceptions";
1115 /* !!! When GCC calls collect2,
1116 it does not know whether it is calling collect2 or ld.
1117 So collect2 cannot meaningfully understand any options
1118 except those ld understands.
1119 If you propose to make GCC pass some other option,
1120 just imagine what will happen if ld is really ld!!! */
1122 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1123 /* After the first file, put in the c++ rt0. */
1126 while ((arg
= *++argv
) != (char *) 0)
1128 *ld1
++ = *ld2
++ = arg
;
1134 #ifdef COLLECT_EXPORT_LIST
1135 /* We want to disable automatic exports on AIX when user
1136 explicitly puts an export list in command line */
1138 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1140 else if (arg
[2] == '6' && arg
[3] == '4')
1146 if (!strcmp (arg
, "-debug"))
1148 /* Already parsed. */
1157 /* place o_file BEFORE this argument! */
1163 #ifdef COLLECT_EXPORT_LIST
1165 /* Resolving full library name. */
1166 const char *s
= resolve_lib_name (arg
+2);
1168 /* If we will use an import list for this library,
1169 we should exclude it from ld args. */
1170 if (use_import_list (s
))
1176 /* Saving a full library name. */
1177 add_to_list (&libs
, s
);
1182 #ifdef COLLECT_EXPORT_LIST
1183 /* Saving directories where to search for libraries. */
1185 add_prefix (&cmdline_lib_dirs
, arg
+2);
1191 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1193 #ifdef SWITCHES_NEED_SPACES
1194 && ! index (SWITCHES_NEED_SPACES
, arg
[1])
1198 output_file
= &arg
[2];
1207 if (arg
[2] == '\0' && do_collecting
)
1209 /* We must strip after the nm run, otherwise C++ linking
1210 will not work. Thus we strip in the second ld run, or
1211 else with strip if there is no second ld run. */
1223 else if ((p
= rindex (arg
, '.')) != (char *) 0
1224 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1225 || strcmp (p
, ".so") == 0))
1234 /* place o_file BEFORE this argument! */
1242 #ifdef COLLECT_EXPORT_LIST
1243 /* libraries can be specified directly, i.e. without -l flag. */
1246 /* If we will use an import list for this library,
1247 we should exclude it from ld args. */
1248 if (use_import_list (arg
))
1254 /* Saving a full library name. */
1255 add_to_list (&libs
, arg
);
1261 #ifdef COLLECT_EXPORT_LIST
1262 /* This is added only for debugging purposes. */
1265 fprintf (stderr
, "List of libraries:\n");
1266 dump_list (stderr
, "\t", libs
.first
);
1269 /* The AIX linker will discard static constructors in object files if
1270 nothing else in the file is referenced, so look at them first. */
1272 const char **export_object_lst
= (const char **)object_lst
;
1274 while (export_object_lst
< object
)
1275 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1278 struct id
*list
= libs
.first
;
1280 for (; list
; list
= list
->next
)
1281 scan_prog_file (list
->name
, PASS_FIRST
);
1284 if (frame_tables
.number
> 0 && shared_obj
)
1286 /* If there are any frames, then we will need
1287 the frame table handling functions. */
1288 add_to_list (&imports
, "__register_frame_info_table");
1289 add_to_list (&imports
, "__deregister_frame_info");
1294 char *buf
= xmalloc (strlen (export_file
) + 5);
1296 sprintf (buf
, "-bE:%s", export_file
);
1300 exportf
= fopen (export_file
, "w");
1301 if (exportf
== (FILE *) 0)
1302 fatal_perror ("fopen %s", export_file
);
1303 write_aix_file (exportf
, exports
.first
);
1304 if (fclose (exportf
))
1305 fatal_perror ("fclose %s", export_file
);
1310 char *buf
= xmalloc (strlen (import_file
) + 5);
1312 sprintf (buf
, "-bI:%s", import_file
);
1316 importf
= fopen (import_file
, "w");
1317 if (importf
== (FILE *) 0)
1318 fatal_perror ("%s", import_file
);
1319 fputs ("#! .\n", importf
);
1320 write_aix_file (importf
, imports
.first
);
1321 if (fclose (importf
))
1322 fatal_perror ("fclose %s", import_file
);
1327 *c_ptr
= *ld1
= *object
= (char *) 0;
1331 notice ("collect2 version %s", version_string
);
1332 #ifdef TARGET_VERSION
1335 fprintf (stderr
, "\n");
1341 fprintf (stderr
, "ld_file_name = %s\n",
1342 (ld_file_name
? ld_file_name
: "not found"));
1343 fprintf (stderr
, "c_file_name = %s\n",
1344 (c_file_name
? c_file_name
: "not found"));
1345 fprintf (stderr
, "nm_file_name = %s\n",
1346 (nm_file_name
? nm_file_name
: "not found"));
1348 fprintf (stderr
, "ldd_file_name = %s\n",
1349 (ldd_file_name
? ldd_file_name
: "not found"));
1351 fprintf (stderr
, "strip_file_name = %s\n",
1352 (strip_file_name
? strip_file_name
: "not found"));
1353 fprintf (stderr
, "c_file = %s\n",
1354 (c_file
? c_file
: "not found"));
1355 fprintf (stderr
, "o_file = %s\n",
1356 (o_file
? o_file
: "not found"));
1358 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1360 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1362 ptr
= getenv ("COLLECT_GCC");
1364 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1366 ptr
= getenv ("COMPILER_PATH");
1368 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1370 ptr
= getenv (LIBRARY_PATH_ENV
);
1372 fprintf (stderr
, "%-20s= %s\n", LIBRARY_PATH_ENV
, ptr
);
1374 fprintf (stderr
, "\n");
1377 /* Load the program, searching all libraries and attempting to provide
1378 undefined symbols from repository information. */
1380 /* On AIX we do this later. */
1381 #ifndef COLLECT_EXPORT_LIST
1382 do_tlink (ld1_argv
, object_lst
);
1385 /* If -r or they will be run via some other method, do not build the
1386 constructor or destructor list, just return now. */
1388 #ifndef COLLECT_EXPORT_LIST
1393 #ifdef COLLECT_EXPORT_LIST
1394 /* Do the link we avoided above if we are exiting. */
1395 do_tlink (ld1_argv
, object_lst
);
1397 /* But make sure we delete the export file we may have created. */
1398 if (export_file
!= 0 && export_file
[0])
1399 maybe_unlink (export_file
);
1400 if (import_file
!= 0 && import_file
[0])
1401 maybe_unlink (import_file
);
1403 maybe_unlink (c_file
);
1404 maybe_unlink (o_file
);
1408 /* Examine the namelist with nm and search it for static constructors
1409 and destructors to call.
1410 Write the constructor and destructor tables to a .s file and reload. */
1412 /* On AIX we already scanned for global constructors/destructors. */
1413 #ifndef COLLECT_EXPORT_LIST
1414 scan_prog_file (output_file
, PASS_FIRST
);
1417 #ifdef SCAN_LIBRARIES
1418 scan_libraries (output_file
);
1423 notice ("%d constructor(s) found\n", constructors
.number
);
1424 notice ("%d destructor(s) found\n", destructors
.number
);
1425 notice ("%d frame table(s) found\n", frame_tables
.number
);
1428 if (constructors
.number
== 0 && destructors
.number
== 0
1429 && frame_tables
.number
== 0
1430 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1431 /* If we will be running these functions ourselves, we want to emit
1432 stubs into the shared library so that we do not have to relink
1433 dependent programs when we add static objects. */
1438 #ifdef COLLECT_EXPORT_LIST
1439 /* Do tlink without additional code generation */
1440 do_tlink (ld1_argv
, object_lst
);
1442 /* Strip now if it was requested on the command line. */
1445 char **real_strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1446 const char ** strip_argv
= (const char **) real_strip_argv
;
1448 strip_argv
[0] = strip_file_name
;
1449 strip_argv
[1] = output_file
;
1450 strip_argv
[2] = (char *) 0;
1451 fork_execute ("strip", real_strip_argv
);
1454 #ifdef COLLECT_EXPORT_LIST
1455 maybe_unlink (export_file
);
1456 maybe_unlink (import_file
);
1458 maybe_unlink (c_file
);
1459 maybe_unlink (o_file
);
1463 /* Sort ctor and dtor lists by priority. */
1464 sort_ids (&constructors
);
1465 sort_ids (&destructors
);
1467 maybe_unlink(output_file
);
1468 outf
= fopen (c_file
, "w");
1469 if (outf
== (FILE *) 0)
1470 fatal_perror ("fopen %s", c_file
);
1472 write_c_file (outf
, c_file
);
1475 fatal_perror ("fclose %s", c_file
);
1477 /* Tell the linker that we have initializer and finalizer functions. */
1478 #ifdef LD_INIT_SWITCH
1479 #ifdef COLLECT_EXPORT_LIST
1481 /* option name + functions + colons + NULL */
1482 char *buf
= xmalloc (strlen (LD_INIT_SWITCH
)
1483 + strlen(initname
) + strlen(fininame
) + 3);
1484 sprintf (buf
, "%s:%s:%s", LD_INIT_SWITCH
, initname
, fininame
);
1488 *ld2
++ = LD_INIT_SWITCH
;
1490 *ld2
++ = LD_FINI_SWITCH
;
1495 #ifdef COLLECT_EXPORT_LIST
1498 /* If we did not add export flag to link arguments before, add it to
1499 second link phase now. No new exports should have been added. */
1500 if (! exports
.first
)
1502 char *buf
= xmalloc (strlen (export_file
) + 5);
1504 sprintf (buf
, "-bE:%s", export_file
);
1508 add_to_list (&exports
, initname
);
1509 add_to_list (&exports
, fininame
);
1510 add_to_list (&exports
, "_GLOBAL__DI");
1511 add_to_list (&exports
, "_GLOBAL__DD");
1512 exportf
= fopen (export_file
, "w");
1513 if (exportf
== (FILE *) 0)
1514 fatal_perror ("fopen %s", export_file
);
1515 write_aix_file (exportf
, exports
.first
);
1516 if (fclose (exportf
))
1517 fatal_perror ("fclose %s", export_file
);
1521 /* End of arguments to second link phase. */
1526 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1527 output_file
, c_file
);
1528 write_c_file (stderr
, "stderr");
1529 fprintf (stderr
, "========== end of c_file\n\n");
1530 #ifdef COLLECT_EXPORT_LIST
1531 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1532 write_aix_file (stderr
, exports
.first
);
1533 fprintf (stderr
, "========== end of export_file\n\n");
1537 /* Assemble the constructor and destructor tables.
1538 Link the tables in with the rest of the program. */
1540 fork_execute ("gcc", c_argv
);
1541 #ifdef COLLECT_EXPORT_LIST
1542 /* On AIX we must call tlink because of possible templates resolution */
1543 do_tlink (ld2_argv
, object_lst
);
1545 /* Otherwise, simply call ld because tlink is already done */
1546 fork_execute ("ld", ld2_argv
);
1548 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1549 constructors/destructors in shared libraries. */
1550 scan_prog_file (output_file
, PASS_SECOND
);
1553 maybe_unlink (c_file
);
1554 maybe_unlink (o_file
);
1556 #ifdef COLLECT_EXPORT_LIST
1557 maybe_unlink (export_file
);
1558 maybe_unlink (import_file
);
1565 /* Wait for a process to finish, and exit if a non-zero status is found. */
1573 pwait (pexecute_pid
, &status
, 0);
1576 if (WIFSIGNALED (status
))
1578 int sig
= WTERMSIG (status
);
1579 error ("%s terminated with signal %d [%s]%s",
1580 prog
, sig
, strsignal(sig
),
1581 status
& 0200 ? "" : ", core dumped");
1582 collect_exit (FATAL_EXIT_CODE
);
1585 if (WIFEXITED (status
))
1586 return WEXITSTATUS (status
);
1595 int ret
= collect_wait (prog
);
1598 error ("%s returned %d exit status", prog
, ret
);
1604 /* Execute a program, and wait for the reply. */
1607 collect_execute (prog
, argv
, redir
)
1614 int redir_handle
= -1;
1615 int stdout_save
= -1;
1616 int stderr_save
= -1;
1624 fprintf (stderr
, "%s", argv
[0]);
1626 notice ("[cannot find %s]", prog
);
1628 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1629 fprintf (stderr
, " %s", str
);
1631 fprintf (stderr
, "\n");
1637 /* If we cannot find a program we need, complain error. Do this here
1638 since we might not end up needing something that we could not find. */
1641 fatal ("cannot find `%s'", prog
);
1645 /* Open response file. */
1646 redir_handle
= open (redir
, O_WRONLY
| O_TRUNC
| O_CREAT
);
1648 /* Duplicate the stdout and stderr file handles
1649 so they can be restored later. */
1650 stdout_save
= dup (STDOUT_FILENO
);
1651 if (stdout_save
== -1)
1652 fatal_perror ("redirecting stdout: %s", redir
);
1653 stderr_save
= dup (STDERR_FILENO
);
1654 if (stderr_save
== -1)
1655 fatal_perror ("redirecting stdout: %s", redir
);
1657 /* Redirect stdout & stderr to our response file. */
1658 dup2 (redir_handle
, STDOUT_FILENO
);
1659 dup2 (redir_handle
, STDERR_FILENO
);
1662 pexecute_pid
= pexecute (argv
[0], argv
, argv
[0], NULL
,
1663 &errmsg_fmt
, &errmsg_arg
,
1664 (PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
));
1668 /* Restore stdout and stderr to their previous settings. */
1669 dup2 (stdout_save
, STDOUT_FILENO
);
1670 dup2 (stderr_save
, STDERR_FILENO
);
1672 /* Close reponse file. */
1673 close (redir_handle
);
1676 if (pexecute_pid
== -1)
1677 fatal_perror (errmsg_fmt
, errmsg_arg
);
1681 fork_execute (prog
, argv
)
1685 collect_execute (prog
, argv
, NULL
);
1689 /* Unlink a file unless we are debugging. */
1698 notice ("[Leaving %s]\n", file
);
1702 static long sequence_number
= 0;
1704 /* Add a name to a linked list. */
1707 add_to_list (head_ptr
, name
)
1708 struct head
*head_ptr
;
1712 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1714 strcpy (newid
->name
, name
);
1716 if (head_ptr
->first
)
1717 head_ptr
->last
->next
= newid
;
1719 head_ptr
->first
= newid
;
1721 /* Check for duplicate symbols. */
1722 for (p
= head_ptr
->first
;
1723 strcmp (name
, p
->name
) != 0;
1728 head_ptr
->last
->next
= 0;
1733 newid
->sequence
= ++sequence_number
;
1734 head_ptr
->last
= newid
;
1738 /* Grab the init priority number from an init function name that
1739 looks like "_GLOBAL_.I.12345.foo". */
1742 extract_init_priority (name
)
1747 while (name
[pos
] == '_')
1749 pos
+= 10; /* strlen ("GLOBAL__X_") */
1751 /* Extract init_p number from ctor/dtor name. */
1752 pri
= atoi (name
+ pos
);
1753 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1756 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1757 ctors will be run from right to left, dtors from left to right. */
1761 struct head
*head_ptr
;
1763 /* id holds the current element to insert. id_next holds the next
1764 element to insert. id_ptr iterates through the already sorted elements
1765 looking for the place to insert id. */
1766 struct id
*id
, *id_next
, **id_ptr
;
1768 id
= head_ptr
->first
;
1770 /* We don't have any sorted elements yet. */
1771 head_ptr
->first
= NULL
;
1773 for (; id
; id
= id_next
)
1776 id
->sequence
= extract_init_priority (id
->name
);
1778 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1780 /* If the sequence numbers are the same, we put the id from the
1781 file later on the command line later in the list. */
1782 || id
->sequence
> (*id_ptr
)->sequence
1783 /* Hack: do lexical compare, too.
1784 || (id->sequence == (*id_ptr)->sequence
1785 && strcmp (id->name, (*id_ptr)->name) > 0) */
1794 /* Now set the sequence numbers properly so write_c_file works. */
1795 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1796 id
->sequence
= ++sequence_number
;
1799 /* Write: `prefix', the names on list LIST, `suffix'. */
1802 write_list (stream
, prefix
, list
)
1809 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1814 #ifdef COLLECT_EXPORT_LIST
1815 /* This function is really used only on AIX, but may be useful. */
1817 is_in_list (prefix
, list
)
1823 if (!strcmp (prefix
, list
->name
)) return 1;
1830 /* Added for debugging purpose. */
1831 #ifdef COLLECT_EXPORT_LIST
1833 dump_list (stream
, prefix
, list
)
1840 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1848 dump_prefix_list (stream
, prefix
, list
)
1851 struct prefix_list
*list
;
1855 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1862 write_list_with_asm (stream
, prefix
, list
)
1869 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1870 prefix
, list
->sequence
, list
->name
);
1875 /* Write out the constructor and destructor tables statically (for a shared
1876 object), along with the functions to execute them. */
1879 write_c_file_stat (stream
, name
)
1881 const char *name ATTRIBUTE_UNUSED
;
1885 int frames
= (frame_tables
.number
> 0);
1887 /* Figure out name of output_file, stripping off .so version. */
1888 p
= rindex (output_file
, '/');
1904 if (strncmp (q
, ".so", 3) == 0)
1913 /* q points to null at end of the string (or . of the .so version) */
1914 prefix
= xmalloc (q
- p
+ 1);
1915 strncpy (prefix
, p
, q
- p
);
1917 for (r
= prefix
; *r
; r
++)
1918 if (!ISALNUM ((unsigned char)*r
))
1921 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1922 output_file
, prefix
);
1924 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1925 initname
= xmalloc (strlen (prefix
) + sizeof (INIT_NAME_FORMAT
) - 2);
1926 sprintf (initname
, INIT_NAME_FORMAT
, prefix
);
1928 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1929 fininame
= xmalloc (strlen (prefix
) + sizeof (FINI_NAME_FORMAT
) - 2);
1930 sprintf (fininame
, FINI_NAME_FORMAT
, prefix
);
1934 /* Write the tables as C code */
1936 fprintf (stream
, "static int count;\n");
1937 fprintf (stream
, "typedef void entry_pt();\n");
1938 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1942 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1944 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1945 write_list (stream
, "\t\t&", frame_tables
.first
);
1946 fprintf (stream
, "\t0\n};\n");
1948 /* This must match what's in frame.h. */
1949 fprintf (stream
, "struct object {\n");
1950 fprintf (stream
, " void *pc_begin;\n");
1951 fprintf (stream
, " void *pc_end;\n");
1952 fprintf (stream
, " void *fde_begin;\n");
1953 fprintf (stream
, " void *fde_array;\n");
1954 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1955 fprintf (stream
, " struct object *next;\n");
1956 fprintf (stream
, "};\n");
1958 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1959 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1961 fprintf (stream
, "static void reg_frame () {\n");
1962 fprintf (stream
, "\tstatic struct object ob;\n");
1963 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1964 fprintf (stream
, "\t}\n");
1966 fprintf (stream
, "static void dereg_frame () {\n");
1967 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1968 fprintf (stream
, "\t}\n");
1971 fprintf (stream
, "void %s() {\n", initname
);
1972 if (constructors
.number
> 0 || frames
)
1974 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1975 write_list (stream
, "\t\t", constructors
.first
);
1977 fprintf (stream
, "\treg_frame,\n");
1978 fprintf (stream
, "\t};\n");
1979 fprintf (stream
, "\tentry_pt **p;\n");
1980 fprintf (stream
, "\tif (count++ != 0) return;\n");
1981 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1982 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1985 fprintf (stream
, "\t++count;\n");
1986 fprintf (stream
, "}\n");
1987 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1988 fprintf (stream
, "void %s() {\n", fininame
);
1989 if (destructors
.number
> 0 || frames
)
1991 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1992 write_list (stream
, "\t\t", destructors
.first
);
1994 fprintf (stream
, "\tdereg_frame,\n");
1995 fprintf (stream
, "\t};\n");
1996 fprintf (stream
, "\tentry_pt **p;\n");
1997 fprintf (stream
, "\tif (--count != 0) return;\n");
1998 fprintf (stream
, "\tp = dtors;\n");
1999 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
2000 destructors
.number
+ frames
);
2002 fprintf (stream
, "}\n");
2006 fprintf (stream
, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname
);
2007 fprintf (stream
, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame
);
2011 /* Write the constructor/destructor tables. */
2013 #ifndef LD_INIT_SWITCH
2015 write_c_file_glob (stream
, name
)
2017 const char *name ATTRIBUTE_UNUSED
;
2019 /* Write the tables as C code */
2021 int frames
= (frame_tables
.number
> 0);
2023 fprintf (stream
, "typedef void entry_pt();\n\n");
2025 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
2029 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
2031 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
2032 write_list (stream
, "\t\t&", frame_tables
.first
);
2033 fprintf (stream
, "\t0\n};\n");
2035 /* This must match what's in frame.h. */
2036 fprintf (stream
, "struct object {\n");
2037 fprintf (stream
, " void *pc_begin;\n");
2038 fprintf (stream
, " void *pc_end;\n");
2039 fprintf (stream
, " void *fde_begin;\n");
2040 fprintf (stream
, " void *fde_array;\n");
2041 fprintf (stream
, " __SIZE_TYPE__ count;\n");
2042 fprintf (stream
, " struct object *next;\n");
2043 fprintf (stream
, "};\n");
2045 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2046 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2048 fprintf (stream
, "static void reg_frame () {\n");
2049 fprintf (stream
, "\tstatic struct object ob;\n");
2050 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2051 fprintf (stream
, "\t}\n");
2053 fprintf (stream
, "static void dereg_frame () {\n");
2054 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2055 fprintf (stream
, "\t}\n");
2058 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2059 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2060 write_list (stream
, "\t", constructors
.first
);
2062 fprintf (stream
, "\treg_frame,\n");
2063 fprintf (stream
, "\t0\n};\n\n");
2065 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2067 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2068 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2069 write_list (stream
, "\t", destructors
.first
);
2071 fprintf (stream
, "\tdereg_frame,\n");
2072 fprintf (stream
, "\t0\n};\n\n");
2074 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2075 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2077 #endif /* ! LD_INIT_SWITCH */
2080 write_c_file (stream
, name
)
2084 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2085 #ifndef LD_INIT_SWITCH
2087 write_c_file_glob (stream
, name
);
2090 write_c_file_stat (stream
, name
);
2091 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2094 #ifdef COLLECT_EXPORT_LIST
2096 write_aix_file (stream
, list
)
2100 for (; list
; list
= list
->next
)
2102 fputs (list
->name
, stream
);
2103 putc ('\n', stream
);
2108 #ifdef OBJECT_FORMAT_NONE
2110 /* Generic version to scan the name list of the loaded program for
2111 the symbols g++ uses for static constructors and destructors.
2113 The constructor table begins at __CTOR_LIST__ and contains a count
2114 of the number of pointers (or -1 if the constructors are built in a
2115 separate section by the linker), followed by the pointers to the
2116 constructor functions, terminated with a null pointer. The
2117 destructor table has the same format, and begins at __DTOR_LIST__. */
2120 scan_prog_file (prog_name
, which_pass
)
2121 const char *prog_name
;
2122 enum pass which_pass
;
2124 void (*int_handler
) PARAMS ((int));
2125 void (*quit_handler
) PARAMS ((int));
2126 char *real_nm_argv
[4];
2127 const char **nm_argv
= (const char **) real_nm_argv
;
2134 if (which_pass
== PASS_SECOND
)
2137 /* If we do not have an `nm', complain. */
2138 if (nm_file_name
== 0)
2139 fatal ("cannot find `nm'");
2141 nm_argv
[argc
++] = nm_file_name
;
2142 if (NM_FLAGS
[0] != '\0')
2143 nm_argv
[argc
++] = NM_FLAGS
;
2145 nm_argv
[argc
++] = prog_name
;
2146 nm_argv
[argc
++] = (char *) 0;
2148 if (pipe (pipe_fd
) < 0)
2149 fatal_perror ("pipe");
2151 inf
= fdopen (pipe_fd
[0], "r");
2152 if (inf
== (FILE *) 0)
2153 fatal_perror ("fdopen");
2155 /* Trace if needed. */
2158 const char **p_argv
;
2161 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2162 fprintf (stderr
, " %s", str
);
2164 fprintf (stderr
, "\n");
2170 /* Spawn child nm on pipe */
2173 fatal_perror (VFORK_STRING
);
2175 if (pid
== 0) /* child context */
2178 if (dup2 (pipe_fd
[1], 1) < 0)
2179 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2181 if (close (pipe_fd
[0]) < 0)
2182 fatal_perror ("close %d", pipe_fd
[0]);
2184 if (close (pipe_fd
[1]) < 0)
2185 fatal_perror ("close %d", pipe_fd
[1]);
2187 execv (nm_file_name
, real_nm_argv
);
2188 fatal_perror ("execvp %s", nm_file_name
);
2191 /* Parent context from here on. */
2192 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2194 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2197 if (close (pipe_fd
[1]) < 0)
2198 fatal_perror ("close %d", pipe_fd
[1]);
2201 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2203 /* Read each line of nm output. */
2204 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2209 /* If it contains a constructor or destructor name, add the name
2210 to the appropriate list. */
2212 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2213 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2220 /* Find the end of the symbol name.
2221 Do not include `|', because Encore nm can tack that on the end. */
2222 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2228 switch (is_ctor_dtor (name
))
2231 if (which_pass
!= PASS_LIB
)
2232 add_to_list (&constructors
, name
);
2236 if (which_pass
!= PASS_LIB
)
2237 add_to_list (&destructors
, name
);
2241 if (which_pass
!= PASS_LIB
)
2242 fatal ("init function found in object %s", prog_name
);
2243 #ifndef LD_INIT_SWITCH
2244 add_to_list (&constructors
, name
);
2249 if (which_pass
!= PASS_LIB
)
2250 fatal ("fini function found in object %s", prog_name
);
2251 #ifndef LD_FINI_SWITCH
2252 add_to_list (&destructors
, name
);
2257 if (which_pass
!= PASS_LIB
)
2258 add_to_list (&frame_tables
, name
);
2261 default: /* not a constructor or destructor */
2266 fprintf (stderr
, "\t%s\n", buf
);
2270 fprintf (stderr
, "\n");
2272 if (fclose (inf
) != 0)
2273 fatal_perror ("fclose");
2275 do_wait (nm_file_name
);
2277 signal (SIGINT
, int_handler
);
2279 signal (SIGQUIT
, quit_handler
);
2283 #if SUNOS4_SHARED_LIBRARIES
2285 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2286 that the output file depends upon and their initialization/finalization
2287 routines, if any. */
2292 #include <sys/mman.h>
2293 #include <sys/param.h>
2295 #include <sys/dir.h>
2297 /* pointers to the object file */
2298 unsigned object
; /* address of memory mapped file */
2299 unsigned objsize
; /* size of memory mapped to file */
2300 char * code
; /* pointer to code segment */
2301 char * data
; /* pointer to data segment */
2302 struct nlist
*symtab
; /* pointer to symbol table */
2303 struct link_dynamic
*ld
;
2304 struct link_dynamic_2
*ld_2
;
2305 struct head libraries
;
2307 /* Map the file indicated by NAME into memory and store its address. */
2309 static void mapfile
PARAMS ((const char *));
2317 if ((fp
= open (name
, O_RDONLY
)) == -1)
2318 fatal ("unable to open file '%s'", name
);
2319 if (fstat (fp
, &s
) == -1)
2320 fatal ("unable to stat file '%s'", name
);
2322 objsize
= s
.st_size
;
2323 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2325 if (object
== (unsigned)-1)
2326 fatal ("unable to mmap file '%s'", name
);
2331 /* Helpers for locatelib. */
2333 static const char *libname
;
2335 static int libselect
PARAMS ((struct direct
*));
2341 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2344 /* If one file has an additional numeric extension past LIBNAME, then put
2345 that one first in the sort. If both files have additional numeric
2346 extensions, then put the one with the higher number first in the sort.
2348 We must verify that the extension is numeric, because Sun saves the
2349 original versions of patched libraries with a .FCS extension. Files with
2350 invalid extensions must go last in the sort, so that they will not be used. */
2351 static int libcompare
PARAMS ((struct direct
**, struct direct
**));
2355 struct direct
**d1
, **d2
;
2357 int i1
, i2
= strlen (libname
);
2358 char *e1
= (*d1
)->d_name
+ i2
;
2359 char *e2
= (*d2
)->d_name
+ i2
;
2361 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2362 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2366 i1
= strtol (e1
, &e1
, 10);
2367 i2
= strtol (e2
, &e2
, 10);
2374 /* It has a valid numeric extension, prefer this one. */
2375 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2377 /* It has a invalid numeric extension, must prefer the other one. */
2383 /* It has a valid numeric extension, prefer this one. */
2384 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2386 /* It has a invalid numeric extension, must prefer the other one. */
2394 /* Given the name NAME of a dynamic dependency, find its pathname and add
2395 it to the list of libraries. */
2396 static void locatelib
PARAMS ((const char *));
2402 static const char **l
;
2404 char buf
[MAXPATHLEN
];
2412 /* counting elements in array, need 1 extra for null */
2414 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2418 for (; *ld_rules
!= 0; ld_rules
++)
2419 if (*ld_rules
== ':')
2421 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2422 ldr
= xstrdup (ld_rules
);
2424 p
= getenv ("LD_LIBRARY_PATH");
2429 for (q
= p
; *q
!= 0; q
++)
2434 l
= (const char **) xmalloc ((cnt
+ 3) * sizeof (char *));
2439 for (; *ldr
!= 0; ldr
++)
2449 for (; *q
!= 0; q
++)
2456 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2459 *pp
++ = "/usr/local/lib";
2463 for (pp
= l
; *pp
!= 0 ; pp
++)
2465 struct direct
**namelist
;
2467 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2469 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2470 add_to_list (&libraries
, buf
);
2472 fprintf (stderr
, "%s\n", buf
);
2479 notice ("not found\n");
2481 fatal ("dynamic dependency %s not found", name
);
2485 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2486 that it depends upon and any constructors or destructors they contain. */
2489 scan_libraries (prog_name
)
2490 const char *prog_name
;
2492 struct exec
*header
;
2494 struct link_object
*lo
;
2495 char buff
[MAXPATHLEN
];
2498 mapfile (prog_name
);
2499 header
= (struct exec
*)object
;
2500 if (N_BADMAG (*header
))
2501 fatal ("bad magic number in file '%s'", prog_name
);
2502 if (header
->a_dynamic
== 0)
2505 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2506 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2507 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2509 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2512 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2518 ld
= (struct link_dynamic
*) data
;
2523 notice ("dynamic dependencies.\n");
2525 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2526 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2527 lo
= (struct link_object
*) lo
->lo_next
)
2530 lo
= (struct link_object
*) ((long) lo
+ code
);
2531 name
= (char *) (code
+ lo
->lo_name
);
2535 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2536 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2542 fprintf (stderr
, "\t%s\n", name
);
2543 add_to_list (&libraries
, name
);
2548 fprintf (stderr
, "\n");
2550 /* now iterate through the library list adding their symbols to
2552 for (list
= libraries
.first
; list
; list
= list
->next
)
2553 scan_prog_file (list
->name
, PASS_LIB
);
2556 #else /* SUNOS4_SHARED_LIBRARIES */
2559 /* Use the List Dynamic Dependencies program to find shared libraries that
2560 the output file depends upon and their initialization/finalization
2561 routines, if any. */
2564 scan_libraries (prog_name
)
2565 const char *prog_name
;
2567 static struct head libraries
; /* list of shared libraries found */
2569 void (*int_handler
) PARAMS ((int));
2570 void (*quit_handler
) PARAMS ((int));
2571 char *real_ldd_argv
[4];
2572 const char **ldd_argv
= (const char **) real_ldd_argv
;
2579 /* If we do not have an `ldd', complain. */
2580 if (ldd_file_name
== 0)
2582 error ("cannot find `ldd'");
2586 ldd_argv
[argc
++] = ldd_file_name
;
2587 ldd_argv
[argc
++] = prog_name
;
2588 ldd_argv
[argc
++] = (char *) 0;
2590 if (pipe (pipe_fd
) < 0)
2591 fatal_perror ("pipe");
2593 inf
= fdopen (pipe_fd
[0], "r");
2594 if (inf
== (FILE *) 0)
2595 fatal_perror ("fdopen");
2597 /* Trace if needed. */
2600 const char **p_argv
;
2603 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2604 fprintf (stderr
, " %s", str
);
2606 fprintf (stderr
, "\n");
2612 /* Spawn child ldd on pipe */
2615 fatal_perror (VFORK_STRING
);
2617 if (pid
== 0) /* child context */
2620 if (dup2 (pipe_fd
[1], 1) < 0)
2621 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2623 if (close (pipe_fd
[0]) < 0)
2624 fatal_perror ("close %d", pipe_fd
[0]);
2626 if (close (pipe_fd
[1]) < 0)
2627 fatal_perror ("close %d", pipe_fd
[1]);
2629 execv (ldd_file_name
, real_ldd_argv
);
2630 fatal_perror ("execv %s", ldd_file_name
);
2633 /* Parent context from here on. */
2634 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2636 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2639 if (close (pipe_fd
[1]) < 0)
2640 fatal_perror ("close %d", pipe_fd
[1]);
2643 notice ("\nldd output with constructors/destructors.\n");
2645 /* Read each line of ldd output. */
2646 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2649 char *name
, *end
, *p
= buf
;
2651 /* Extract names of libraries and add to list. */
2652 PARSE_LDD_OUTPUT (p
);
2657 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2658 fatal ("dynamic dependency %s not found", buf
);
2660 /* Find the end of the symbol name. */
2662 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2667 if (access (name
, R_OK
) == 0)
2668 add_to_list (&libraries
, name
);
2670 fatal ("unable to open dynamic dependency '%s'", buf
);
2673 fprintf (stderr
, "\t%s\n", buf
);
2676 fprintf (stderr
, "\n");
2678 if (fclose (inf
) != 0)
2679 fatal_perror ("fclose");
2681 do_wait (ldd_file_name
);
2683 signal (SIGINT
, int_handler
);
2685 signal (SIGQUIT
, quit_handler
);
2688 /* now iterate through the library list adding their symbols to
2690 for (list
= libraries
.first
; list
; list
= list
->next
)
2691 scan_prog_file (list
->name
, PASS_LIB
);
2694 #endif /* LDD_SUFFIX */
2695 #endif /* SUNOS4_SHARED_LIBRARIES */
2697 #endif /* OBJECT_FORMAT_NONE */
2701 * COFF specific stuff.
2704 #ifdef OBJECT_FORMAT_COFF
2706 #if defined(EXTENDED_COFF)
2707 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2708 # define GCC_SYMENT SYMR
2709 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2710 # define GCC_SYMINC(X) (1)
2711 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2712 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2714 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2715 # define GCC_SYMENT SYMENT
2716 # define GCC_OK_SYMBOL(X) \
2717 (((X).n_sclass == C_EXT) && \
2718 ((X).n_scnum > N_UNDEF) && \
2720 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2721 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2722 # define GCC_UNDEF_SYMBOL(X) \
2723 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2724 # define GCC_SYMINC(X) ((X).n_numaux+1)
2725 # define GCC_SYMZERO(X) 0
2726 # define GCC_CHECK_HDR(X) \
2727 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2728 || (HEADER (X).f_magic == 0757 && aix64_flag))
2731 extern char *ldgetname ();
2733 /* COFF version to scan the name list of the loaded program for
2734 the symbols g++ uses for static constructors and destructors.
2736 The constructor table begins at __CTOR_LIST__ and contains a count
2737 of the number of pointers (or -1 if the constructors are built in a
2738 separate section by the linker), followed by the pointers to the
2739 constructor functions, terminated with a null pointer. The
2740 destructor table has the same format, and begins at __DTOR_LIST__. */
2743 scan_prog_file (prog_name
, which_pass
)
2744 const char *prog_name
;
2745 enum pass which_pass
;
2747 LDFILE
*ldptr
= NULL
;
2748 int sym_index
, sym_count
;
2750 #ifdef COLLECT_EXPORT_LIST
2751 /* Should we generate an import list for given prog_name? */
2752 int import_flag
= (which_pass
== PASS_OBJ
? 0 : use_import_list (prog_name
));
2755 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2758 #ifdef COLLECT_EXPORT_LIST
2759 /* We do not need scanning for some standard C libraries. */
2760 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2763 /* On AIX we have a loop, because there is not much difference
2764 between an object and an archive. This trick allows us to
2765 eliminate scan_libraries() function. */
2769 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2770 non-const char * filename parameter, even though it will not
2771 modify that string. So we must cast away const-ness here,
2772 which will cause -Wcast-qual to burp. */
2773 if ((ldptr
= ldopen ((char *)prog_name
, ldptr
)) != NULL
)
2775 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2776 fatal ("%s: not a COFF file", prog_name
);
2778 if (GCC_CHECK_HDR (ldptr
))
2780 sym_count
= GCC_SYMBOLS (ldptr
);
2781 sym_index
= GCC_SYMZERO (ldptr
);
2783 #ifdef COLLECT_EXPORT_LIST
2784 /* Is current archive member a shared object? */
2785 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2788 while (sym_index
< sym_count
)
2792 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2794 sym_index
+= GCC_SYMINC (symbol
);
2796 if (GCC_OK_SYMBOL (symbol
))
2800 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2801 continue; /* should never happen */
2803 #ifdef XCOFF_DEBUGGING_INFO
2804 /* All AIX function names have a duplicate entry
2805 beginning with a dot. */
2810 switch (is_ctor_dtor (name
))
2814 add_to_list (&constructors
, name
);
2815 #ifdef COLLECT_EXPORT_LIST
2816 if (which_pass
== PASS_OBJ
)
2817 add_to_list (&exports
, name
);
2818 /* If this symbol was undefined and we are building
2819 an import list, we should add a symbol to this
2823 && is_in_list (name
, undefined
.first
))
2824 add_to_list (&imports
, name
);
2830 add_to_list (&destructors
, name
);
2831 #ifdef COLLECT_EXPORT_LIST
2832 if (which_pass
== PASS_OBJ
)
2833 add_to_list (&exports
, name
);
2834 /* If this symbol was undefined and we are building
2835 an import list, we should add a symbol to this
2839 && is_in_list (name
, undefined
.first
))
2840 add_to_list (&imports
, name
);
2844 #ifdef COLLECT_EXPORT_LIST
2846 #ifndef LD_INIT_SWITCH
2848 add_to_list (&constructors
, name
);
2853 #ifndef LD_INIT_SWITCH
2855 add_to_list (&destructors
, name
);
2862 add_to_list (&frame_tables
, name
);
2863 #ifdef COLLECT_EXPORT_LIST
2864 if (which_pass
== PASS_OBJ
)
2865 add_to_list (&exports
, name
);
2866 /* If we are building an import list, we
2867 should add the symbol to the list.
2868 We'd like to do it only if the symbol
2869 is not defined, but we can't tell
2870 that here (it is only known whether a symbol
2871 is referenced and not defined, but who
2872 would reference an EH table entry?). */
2875 add_to_list (&imports
, name
);
2879 default: /* not a constructor or destructor */
2880 #ifdef COLLECT_EXPORT_LIST
2881 /* If we are building a shared object on AIX we need
2882 to explicitly export all global symbols or add
2883 them to import list. */
2886 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2887 add_to_list (&exports
, name
);
2888 else if (! is_shared
2889 && which_pass
== PASS_FIRST
2891 && is_in_list(name
, undefined
.first
))
2892 add_to_list (&imports
, name
);
2899 #if !defined(EXTENDED_COFF)
2900 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2901 symbol
.n_scnum
, symbol
.n_sclass
,
2902 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2906 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2907 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2910 #ifdef COLLECT_EXPORT_LIST
2911 /* If we are building a shared object we should collect
2912 information about undefined symbols for later
2913 import list generation. */
2914 else if (shared_obj
&& GCC_UNDEF_SYMBOL (symbol
))
2918 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2919 continue; /* should never happen */
2921 /* All AIX function names have a duplicate entry
2922 beginning with a dot. */
2925 add_to_list (&undefined
, name
);
2930 #ifdef COLLECT_EXPORT_LIST
2933 /* If archive contains both 32-bit and 64-bit objects,
2934 we want to skip objects in other mode so mismatch normal. */
2936 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2937 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2943 fatal ("%s: cannot open as COFF file", prog_name
);
2945 #ifdef COLLECT_EXPORT_LIST
2946 /* On AIX loop continues while there are more members in archive. */
2948 while (ldclose (ldptr
) == FAILURE
);
2950 /* Otherwise we simply close ldptr. */
2951 (void) ldclose(ldptr
);
2956 #ifdef COLLECT_EXPORT_LIST
2958 /* This new function is used to decide whether we should
2959 generate import list for an object or to use it directly. */
2961 use_import_list (prog_name
)
2962 const char *prog_name
;
2966 /* If we do not build a shared object then import list should not be used. */
2967 if (! shared_obj
) return 0;
2969 /* Currently we check only for libgcc, but this can be changed in future. */
2970 p
= strstr (prog_name
, "libgcc.a");
2971 if (p
!= 0 && (strlen (p
) == sizeof ("libgcc.a") - 1))
2976 /* Given a library name without "lib" prefix, this function
2977 returns a full library name including a path. */
2979 resolve_lib_name (name
)
2985 for (i
= 0; libpaths
[i
]; i
++)
2986 if (libpaths
[i
]->max_len
> l
)
2987 l
= libpaths
[i
]->max_len
;
2989 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2991 for (i
= 0; libpaths
[i
]; i
++)
2993 struct prefix_list
*list
= libpaths
[i
]->plist
;
2994 for (; list
; list
= list
->next
)
2996 for (j
= 0; libexts
[j
]; j
++)
2998 /* The following lines are needed because path_prefix list
2999 may contain directories both with trailing '/' and
3002 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
3004 sprintf (lib_buf
, "%s%slib%s.%s",
3005 list
->prefix
, p
, name
, libexts
[j
]);
3006 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
3007 if (file_exists (lib_buf
))
3009 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
3016 fprintf (stderr
, "not found\n");
3018 fatal ("Library lib%s not found", name
);
3022 /* Array of standard AIX libraries which should not
3023 be scanned for ctors/dtors. */
3024 static const char *aix_std_libs
[] = {
3029 "/usr/lib/libc_r.a",
3030 "/usr/lib/threads/libc.a",
3031 "/usr/ccs/lib/libc.a",
3032 "/usr/ccs/lib/libc_r.a",
3036 /* This function checks the filename and returns 1
3037 if this name matches the location of a standard AIX library. */
3039 ignore_library (name
)
3042 const char **p
= &aix_std_libs
[0];
3043 while (*p
++ != NULL
)
3044 if (! strcmp (name
, *p
)) return 1;
3050 #endif /* OBJECT_FORMAT_COFF */
3054 * OSF/rose specific stuff.
3057 #ifdef OBJECT_FORMAT_ROSE
3059 /* Union of the various load commands */
3061 typedef union load_union
3063 ldc_header_t hdr
; /* common header */
3064 load_cmd_map_command_t map
; /* map indexing other load cmds */
3065 interpreter_command_t iprtr
; /* interpreter pathname */
3066 strings_command_t str
; /* load commands strings section */
3067 region_command_t region
; /* region load command */
3068 reloc_command_t reloc
; /* relocation section */
3069 package_command_t pkg
; /* package load command */
3070 symbols_command_t sym
; /* symbol sections */
3071 entry_command_t ent
; /* program start section */
3072 gen_info_command_t info
; /* object information */
3073 func_table_command_t func
; /* function constructors/destructors */
3076 /* Structure to point to load command and data section in memory. */
3078 typedef struct load_all
3080 load_union_t
*load
; /* load command */
3081 char *section
; /* pointer to section */
3084 /* Structure to contain information about a file mapped into memory. */
3088 char *start
; /* start of map */
3089 char *name
; /* filename */
3090 long size
; /* size of the file */
3091 long rounded_size
; /* size rounded to page boundary */
3092 int fd
; /* file descriptor */
3093 int rw
; /* != 0 if opened read/write */
3094 int use_mmap
; /* != 0 if mmap'ed */
3097 extern int decode_mach_o_hdr ();
3098 extern int encode_mach_o_hdr ();
3100 static void add_func_table
PARAMS ((mo_header_t
*, load_all_t
*,
3101 symbol_info_t
*, int));
3102 static void print_header
PARAMS ((mo_header_t
*));
3103 static void print_load_command
PARAMS ((load_union_t
*, size_t, int));
3104 static void bad_header
PARAMS ((int));
3105 static struct file_info
*read_file
PARAMS ((const char *, int, int));
3106 static void end_file
PARAMS ((struct file_info
*));
3108 /* OSF/rose specific version to scan the name list of the loaded
3109 program for the symbols g++ uses for static constructors and
3112 The constructor table begins at __CTOR_LIST__ and contains a count
3113 of the number of pointers (or -1 if the constructors are built in a
3114 separate section by the linker), followed by the pointers to the
3115 constructor functions, terminated with a null pointer. The
3116 destructor table has the same format, and begins at __DTOR_LIST__. */
3119 scan_prog_file (prog_name
, which_pass
)
3120 const char *prog_name
;
3121 enum pass which_pass
;
3125 load_all_t
*load_array
;
3126 load_all_t
*load_end
;
3127 load_all_t
*load_cmd
;
3128 int symbol_load_cmds
;
3134 struct file_info
*obj_file
;
3136 mo_lcid_t cmd_strings
= -1;
3137 symbol_info_t
*main_sym
= 0;
3138 int rw
= (which_pass
!= PASS_FIRST
);
3140 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3142 fatal_perror ("open %s", prog_name
);
3144 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3145 obj
= obj_file
->start
;
3147 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3148 if (status
!= MO_HDR_CONV_SUCCESS
)
3149 bad_header (status
);
3152 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3153 since the hardware will automatically swap bytes for us on loading little endian
3156 #ifndef CROSS_COMPILE
3157 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3158 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3159 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3160 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3161 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3162 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3163 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3165 fatal ("incompatibilities between object file & expected values");
3170 print_header (&hdr
);
3172 offset
= hdr
.moh_first_cmd_off
;
3173 load_end
= load_array
3174 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3176 /* Build array of load commands, calculating the offsets */
3177 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3179 load_union_t
*load_hdr
; /* load command header */
3181 load_cmd
= load_end
++;
3182 load_hdr
= (load_union_t
*) (obj
+ offset
);
3184 /* If modifying the program file, copy the header. */
3187 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3188 bcopy ((char *)load_hdr
, (char *)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
3191 /* null out old command map, because we will rewrite at the end. */
3192 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3194 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3195 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3199 load_cmd
->load
= load_hdr
;
3200 if (load_hdr
->hdr
.ldci_section_off
> 0)
3201 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3204 print_load_command (load_hdr
, offset
, i
);
3206 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3209 /* If the last command is the load command map and is not undefined,
3210 decrement the count of load commands. */
3211 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3214 hdr
.moh_n_load_cmds
--;
3217 /* Go through and process each symbol table section. */
3218 symbol_load_cmds
= 0;
3219 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3221 load_union_t
*load_hdr
= load_cmd
->load
;
3223 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3229 const char *kind
= "unknown";
3231 switch (load_hdr
->sym
.symc_kind
)
3233 case SYMC_IMPORTS
: kind
= "imports"; break;
3234 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3235 case SYMC_STABS
: kind
= "stabs"; break;
3238 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3239 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3242 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3245 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3246 if (str_sect
== (char *) 0)
3247 fatal ("string section missing");
3249 if (load_cmd
->section
== (char *) 0)
3250 fatal ("section pointer missing");
3252 num_syms
= load_hdr
->sym
.symc_nentries
;
3253 for (i
= 0; i
< num_syms
; i
++)
3255 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3256 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3263 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3265 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3275 switch (is_ctor_dtor (name
))
3278 add_to_list (&constructors
, name
);
3282 add_to_list (&destructors
, name
);
3285 default: /* not a constructor or destructor */
3291 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3292 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3297 if (symbol_load_cmds
== 0)
3298 fatal ("no symbol table found");
3300 /* Update the program file now, rewrite header and load commands. At present,
3301 we assume that there is enough space after the last load command to insert
3302 one more. Since the first section written out is page aligned, and the
3303 number of load commands is small, this is ok for the present. */
3307 load_union_t
*load_map
;
3310 if (cmd_strings
== -1)
3311 fatal ("no cmd_strings found");
3313 /* Add __main to initializer list.
3314 If we are building a program instead of a shared library, do not
3315 do anything, since in the current version, you cannot do mallocs
3316 and such in the constructors. */
3318 if (main_sym
!= (symbol_info_t
*) 0
3319 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3320 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3323 notice ("\nUpdating header and load commands.\n\n");
3325 hdr
.moh_n_load_cmds
++;
3326 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3328 /* Create new load command map. */
3330 notice ("load command map, %d cmds, new size %ld.\n",
3331 (int) hdr
.moh_n_load_cmds
, (long) size
);
3333 load_map
= (load_union_t
*) xcalloc (1, size
);
3334 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3335 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3336 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3337 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3338 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3340 offset
= hdr
.moh_first_cmd_off
;
3341 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3343 load_map
->map
.lcm_map
[i
] = offset
;
3344 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3345 hdr
.moh_load_map_cmd_off
= offset
;
3347 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3350 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3353 print_header (&hdr
);
3356 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3357 if (status
!= MO_HDR_CONV_SUCCESS
)
3358 bad_header (status
);
3361 notice ("writing load commands.\n\n");
3363 /* Write load commands */
3364 offset
= hdr
.moh_first_cmd_off
;
3365 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3367 load_union_t
*load_hdr
= load_array
[i
].load
;
3368 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3371 print_load_command (load_hdr
, offset
, i
);
3373 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3378 end_file (obj_file
);
3380 if (close (prog_fd
))
3381 fatal_perror ("close %s", prog_name
);
3384 fprintf (stderr
, "\n");
3388 /* Add a function table to the load commands to call a function
3389 on initiation or termination of the process. */
3392 add_func_table (hdr_p
, load_array
, sym
, type
)
3393 mo_header_t
*hdr_p
; /* pointer to global header */
3394 load_all_t
*load_array
; /* array of ptrs to load cmds */
3395 symbol_info_t
*sym
; /* pointer to symbol entry */
3396 int type
; /* fntc_type value */
3398 /* Add a new load command. */
3399 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3400 int load_index
= num_cmds
- 1;
3401 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3402 load_union_t
*ptr
= xcalloc (1, size
);
3403 load_all_t
*load_cmd
;
3406 /* Set the unresolved address bit in the header to force the loader to be
3407 used, since kernel exec does not call the initialization functions. */
3408 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3410 load_cmd
= &load_array
[load_index
];
3411 load_cmd
->load
= ptr
;
3412 load_cmd
->section
= (char *) 0;
3414 /* Fill in func table load command. */
3415 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3416 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3417 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3418 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3419 ptr
->func
.fntc_type
= type
;
3420 ptr
->func
.fntc_nentries
= 1;
3422 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3423 /* Is the symbol already expressed as (region, offset)? */
3424 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3426 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3427 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3430 /* If not, figure out which region it's in. */
3433 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3436 for (i
= 0; i
< load_index
; i
++)
3438 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3440 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3442 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3443 && addr
>= region_ptr
->regc_addr
.vm_addr
3444 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3446 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3447 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3455 fatal ("could not convert 0x%l.8x into a region", addr
);
3459 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3460 type
== FNTC_INITIALIZATION
? "init" : "term",
3461 (int) ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3462 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3463 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3468 /* Print the global header for an OSF/rose object. */
3471 print_header (hdr_ptr
)
3472 mo_header_t
*hdr_ptr
;
3474 fprintf (stderr
, "\nglobal header:\n");
3475 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3476 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3477 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3478 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3479 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3480 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3481 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3482 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3483 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3484 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3485 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3486 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3487 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3488 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3489 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3491 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3492 fprintf (stderr
, ", relocatable");
3494 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3495 fprintf (stderr
, ", linkable");
3497 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3498 fprintf (stderr
, ", execable");
3500 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3501 fprintf (stderr
, ", executable");
3503 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3504 fprintf (stderr
, ", unresolved");
3506 fprintf (stderr
, "\n\n");
3511 /* Print a short summary of a load command. */
3514 print_load_command (load_hdr
, offset
, number
)
3515 load_union_t
*load_hdr
;
3519 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3520 const char *type_str
= (char *) 0;
3524 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3525 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3526 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3527 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3528 case LDC_REGION
: type_str
= "REGION"; break;
3529 case LDC_RELOC
: type_str
= "RELOC"; break;
3530 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3531 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3532 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3533 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3534 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3538 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3540 (long) load_hdr
->hdr
.ldci_cmd_size
,
3542 (long) load_hdr
->hdr
.ldci_section_off
,
3543 (long) load_hdr
->hdr
.ldci_section_len
);
3545 if (type_str
== (char *) 0)
3546 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3548 else if (type
!= LDC_REGION
)
3549 fprintf (stderr
, ", ty: %s\n", type_str
);
3553 const char *region
= "";
3554 switch (load_hdr
->region
.regc_usage_type
)
3556 case REG_TEXT_T
: region
= ", .text"; break;
3557 case REG_DATA_T
: region
= ", .data"; break;
3558 case REG_BSS_T
: region
= ", .bss"; break;
3559 case REG_GLUE_T
: region
= ", .glue"; break;
3560 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3561 case REG_RDATA_T
: region
= ", .rdata"; break;
3562 case REG_SDATA_T
: region
= ", .sdata"; break;
3563 case REG_SBSS_T
: region
= ", .sbss"; break;
3567 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3569 (long) load_hdr
->region
.regc_vm_addr
,
3570 (long) load_hdr
->region
.regc_vm_size
,
3578 /* Fatal error when {en,de}code_mach_o_header fails. */
3586 case MO_ERROR_BAD_MAGIC
: fatal ("bad magic number");
3587 case MO_ERROR_BAD_HDR_VERS
: fatal ("bad header version");
3588 case MO_ERROR_BAD_RAW_HDR_VERS
: fatal ("bad raw header version");
3589 case MO_ERROR_BUF2SML
: fatal ("raw header buffer too small");
3590 case MO_ERROR_OLD_RAW_HDR_FILE
: fatal ("old raw header file");
3591 case MO_ERROR_UNSUPPORTED_VERS
: fatal ("unsupported version");
3593 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3598 /* Read a file into a memory buffer. */
3600 static struct file_info
*
3601 read_file (name
, fd
, rw
)
3602 const char *name
; /* filename */
3603 int fd
; /* file descriptor */
3604 int rw
; /* read/write */
3606 struct stat stat_pkt
;
3607 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3609 static int page_size
;
3612 if (fstat (fd
, &stat_pkt
) < 0)
3613 fatal_perror ("fstat %s", name
);
3616 p
->size
= stat_pkt
.st_size
;
3617 p
->rounded_size
= stat_pkt
.st_size
;
3623 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3626 page_size
= sysconf (_SC_PAGE_SIZE
);
3628 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3629 p
->start
= mmap ((caddr_t
) 0,
3630 (rw
) ? p
->rounded_size
: p
->size
,
3631 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3632 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3636 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3640 #endif /* USE_MMAP */
3645 fprintf (stderr
, "read %s\n", name
);
3648 p
->start
= xmalloc (p
->size
);
3649 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3650 fatal_perror ("lseek %s 0", name
);
3652 len
= read (fd
, p
->start
, p
->size
);
3654 fatal_perror ("read %s", name
);
3657 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3663 /* Do anything necessary to write a file back from memory. */
3667 struct file_info
*ptr
; /* file information block */
3675 fprintf (stderr
, "msync %s\n", ptr
->name
);
3677 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3678 fatal_perror ("msync %s", ptr
->name
);
3682 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3684 if (munmap (ptr
->start
, ptr
->size
))
3685 fatal_perror ("munmap %s", ptr
->name
);
3688 #endif /* USE_MMAP */
3695 fprintf (stderr
, "write %s\n", ptr
->name
);
3697 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3698 fatal_perror ("lseek %s 0", ptr
->name
);
3700 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3702 fatal_perror ("write %s", ptr
->name
);
3704 if (len
!= ptr
->size
)
3705 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3714 #endif /* OBJECT_FORMAT_ROSE */