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 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. */
32 #if ! defined( SIGCHLD ) && defined( SIGCLD )
33 # define SIGCHLD SIGCLD
36 #ifdef vfork /* Autoconf may define this to fork for us. */
37 # define VFORK_STRING "fork"
39 # define VFORK_STRING "vfork"
45 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
46 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
49 #ifndef LIBRARY_PATH_ENV
50 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
61 /* Obstack allocation and deallocation routines. */
62 #define obstack_chunk_alloc xmalloc
63 #define obstack_chunk_free free
65 /* On certain systems, we have code that works by scanning the object file
66 directly. But this code uses system-specific header files and library
67 functions, so turn it off in a cross-compiler. Likewise, the names of
68 the utilities are not correct for a cross-compiler; we have to hope that
69 cross-versions are in the proper directories. */
72 #undef SUNOS4_SHARED_LIBRARIES
73 #undef OBJECT_FORMAT_COFF
74 #undef OBJECT_FORMAT_ROSE
76 #undef REAL_LD_FILE_NAME
77 #undef REAL_NM_FILE_NAME
78 #undef REAL_STRIP_FILE_NAME
81 /* If we cannot use a special method, use the ordinary one:
82 run nm to find what symbols are present.
83 In a cross-compiler, this means you need a cross nm,
84 but that is not quite as unpleasant as special headers. */
86 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
87 #define OBJECT_FORMAT_NONE
90 #ifdef OBJECT_FORMAT_COFF
99 /* Many versions of ldfcn.h define these. */
107 /* Some systems have an ISCOFF macro, but others do not. In some cases
108 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
109 that either do not have an ISCOFF macro in /usr/include or for those
110 where it is wrong. */
113 #define MY_ISCOFF(X) ISCOFF (X)
116 #endif /* OBJECT_FORMAT_COFF */
118 #ifdef OBJECT_FORMAT_ROSE
125 #include <sys/mman.h>
129 #include <mach_o_format.h>
130 #include <mach_o_header.h>
131 #include <mach_o_vals.h>
132 #include <mach_o_types.h>
134 #endif /* OBJECT_FORMAT_ROSE */
136 #ifdef OBJECT_FORMAT_NONE
138 /* Default flags to pass to nm. */
140 #define NM_FLAGS "-n"
143 #endif /* OBJECT_FORMAT_NONE */
145 /* Some systems use __main in a way incompatible with its use in gcc, in these
146 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
147 give the same symbol without quotes for an alternative entry point. You
148 must define both, or neither. */
150 #define NAME__MAIN "__main"
151 #define SYMBOL__MAIN __main
154 /* This must match tree.h. */
155 #define DEFAULT_INIT_PRIORITY 65535
157 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
158 #define SCAN_LIBRARIES
162 int do_collecting
= 1;
164 int do_collecting
= 0;
167 /* Linked lists of constructor and destructor names. */
183 /* Enumeration giving which pass this is for scanning the program file. */
186 PASS_FIRST
, /* without constructors */
187 PASS_OBJ
, /* individual objects */
188 PASS_LIB
, /* looking for shared libraries */
189 PASS_SECOND
/* with constructors linked in */
192 int vflag
; /* true if -v */
193 static int rflag
; /* true if -r */
194 static int strip_flag
; /* true if -s */
195 #ifdef COLLECT_EXPORT_LIST
196 static int export_flag
; /* true if -bE */
197 static int aix64_flag
; /* true if -b64 */
200 int debug
; /* true if -debug */
202 static int shared_obj
; /* true if -shared */
204 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
205 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
206 #ifdef COLLECT_EXPORT_LIST
207 static const char *export_file
; /* <xxx>.x for AIX export list. */
209 const char *ldout
; /* File for ld errors. */
210 static const char *output_file
; /* Output file for ld. */
211 static const char *nm_file_name
; /* pathname of nm */
213 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
215 static const char *strip_file_name
; /* pathname of strip */
216 const char *c_file_name
; /* pathname of gcc */
217 static char *initname
, *fininame
; /* names of init and fini funcs */
219 static struct head constructors
; /* list of constructors found */
220 static struct head destructors
; /* list of destructors found */
221 #ifdef COLLECT_EXPORT_LIST
222 static struct head exports
; /* list of exported 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 ignore_library
PARAMS ((const char *));
301 static char *extract_string
PARAMS ((const char **));
316 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
319 close (fdtmp
[--fdx
]);
325 /* Delete tempfiles and exit function. */
328 collect_exit (status
)
331 if (c_file
!= 0 && c_file
[0])
332 maybe_unlink (c_file
);
334 if (o_file
!= 0 && o_file
[0])
335 maybe_unlink (o_file
);
337 #ifdef COLLECT_EXPORT_LIST
338 if (export_file
!= 0 && export_file
[0])
339 maybe_unlink (export_file
);
342 if (ldout
!= 0 && ldout
[0])
345 maybe_unlink (ldout
);
348 if (status
!= 0 && output_file
!= 0 && output_file
[0])
349 maybe_unlink (output_file
);
355 /* Notify user of a non-error. */
357 notice
VPARAMS ((const char *msgid
, ...))
359 #ifndef ANSI_PROTOTYPES
364 VA_START (ap
, msgid
);
366 #ifndef ANSI_PROTOTYPES
367 msgid
= va_arg (ap
, const char *);
370 vfprintf (stderr
, _(msgid
), ap
);
374 /* Die when sys call fails. */
377 fatal_perror
VPARAMS ((const char * msgid
, ...))
379 #ifndef ANSI_PROTOTYPES
385 VA_START (ap
, msgid
);
387 #ifndef ANSI_PROTOTYPES
388 msgid
= va_arg (ap
, const char *);
391 fprintf (stderr
, "collect2: ");
392 vfprintf (stderr
, _(msgid
), ap
);
393 fprintf (stderr
, ": %s\n", xstrerror (e
));
396 collect_exit (FATAL_EXIT_CODE
);
402 fatal
VPARAMS ((const char * msgid
, ...))
404 #ifndef ANSI_PROTOTYPES
409 VA_START (ap
, msgid
);
411 #ifndef ANSI_PROTOTYPES
412 msgid
= va_arg (ap
, const char *);
415 fprintf (stderr
, "collect2: ");
416 vfprintf (stderr
, _(msgid
), ap
);
417 fprintf (stderr
, "\n");
420 collect_exit (FATAL_EXIT_CODE
);
423 /* Write error message. */
426 error
VPARAMS ((const char * msgid
, ...))
428 #ifndef ANSI_PROTOTYPES
433 VA_START (ap
, msgid
);
435 #ifndef ANSI_PROTOTYPES
436 msgid
= va_arg (ap
, const char *);
439 fprintf (stderr
, "collect2: ");
440 vfprintf (stderr
, _(msgid
), ap
);
441 fprintf (stderr
, "\n");
445 /* In case obstack is linked in, and abort is defined to fancy_abort,
446 provide a default entry. */
451 fatal ("internal error");
458 if (c_file
!= 0 && c_file
[0])
459 maybe_unlink (c_file
);
461 if (o_file
!= 0 && o_file
[0])
462 maybe_unlink (o_file
);
464 if (ldout
!= 0 && ldout
[0])
465 maybe_unlink (ldout
);
467 #ifdef COLLECT_EXPORT_LIST
468 if (export_file
!= 0 && export_file
[0])
469 maybe_unlink (export_file
);
472 signal (signo
, SIG_DFL
);
473 kill (getpid (), signo
);
481 return access (name
, R_OK
) == 0;
484 /* Parse a reasonable subset of shell quoting syntax. */
501 obstack_1grow (&temporary_obstack
, c
);
502 else if (! inside
&& c
== ' ')
504 else if (! inside
&& c
== '\\')
509 obstack_1grow (&temporary_obstack
, c
);
512 obstack_1grow (&temporary_obstack
, '\0');
514 return obstack_finish (&temporary_obstack
);
521 FILE *stream
= fopen (name
, "r");
522 int no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
529 while (c
= getc (stream
),
530 c
!= EOF
&& (ISALNUM (c
) || c
== '_' || c
== '$' || c
== '.'))
531 obstack_1grow (&temporary_obstack
, c
);
532 if (obstack_object_size (&temporary_obstack
) > 0)
534 const char *word
, *p
;
536 obstack_1grow (&temporary_obstack
, '\0');
537 word
= obstack_finish (&temporary_obstack
);
540 ++word
, putc ('.', stderr
);
542 if (*p
== '_' && prepends_underscore
)
548 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
);
553 fputs (result
, stderr
);
555 diff
= strlen (word
) - strlen (result
);
557 --diff
, putc (' ', stderr
);
558 while (diff
< 0 && c
== ' ')
559 ++diff
, c
= getc (stream
);
564 fputs (word
, stderr
);
567 obstack_free (&temporary_obstack
, temporary_firstobj
);
576 /* Decide whether the given symbol is: a constructor (1), a destructor
577 (2), a routine in a shared object that calls all the constructors
578 (3) or destructors (4), a DWARF exception-handling table (5), or
579 nothing special (0). */
585 struct names
{ const char *name
; int len
; int ret
; int two_underscores
; };
587 register struct names
*p
;
589 register const char *orig_s
= s
;
591 static struct names special
[] = {
592 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
593 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
594 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
595 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
596 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
597 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
598 cfront has its own linker procedure to collect them;
599 if collect2 gets them too, they get collected twice
600 when the cfront procedure is run and the compiler used
601 for linking happens to be GCC. */
602 { "sti__", sizeof ("sti__")-1, 1, 1 },
603 { "std__", sizeof ("std__")-1, 2, 1 },
604 #endif /* CFRONT_LOSSAGE */
608 while ((ch
= *s
) == '_')
614 for (p
= &special
[0]; p
->len
> 0; p
++)
617 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
618 && strncmp(s
, p
->name
, p
->len
) == 0)
626 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
627 and one from the PATH variable. */
629 static struct path_prefix cpath
, path
;
632 /* This is the name of the target machine. We use it to form the name
633 of the files to execute. */
635 static const char *const target_machine
= TARGET_MACHINE
;
638 /* Search for NAME using prefix list PPREFIX. We only look for executable
641 Return 0 if not found, otherwise return its name, allocated with malloc. */
644 find_a_file (pprefix
, name
)
645 struct path_prefix
*pprefix
;
649 struct prefix_list
*pl
;
650 int len
= pprefix
->max_len
+ strlen (name
) + 1;
653 fprintf (stderr
, "Looking for '%s'\n", name
);
655 #ifdef EXECUTABLE_SUFFIX
656 len
+= strlen (EXECUTABLE_SUFFIX
);
659 temp
= xmalloc (len
);
661 /* Determine the filename to execute (special case for absolute paths). */
664 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
665 || (*name
&& name
[1] == ':')
669 if (access (name
, X_OK
) == 0)
674 fprintf (stderr
, " - found: absolute path\n");
679 #ifdef EXECUTABLE_SUFFIX
680 /* Some systems have a suffix for executable files.
681 So try appending that. */
683 strcat (temp
, EXECUTABLE_SUFFIX
);
685 if (access (temp
, X_OK
) == 0)
690 fprintf (stderr
, " - failed to locate using absolute path\n");
693 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
697 strcpy (temp
, pl
->prefix
);
700 if (stat (temp
, &st
) >= 0
701 && ! S_ISDIR (st
.st_mode
)
702 && access (temp
, X_OK
) == 0)
705 #ifdef EXECUTABLE_SUFFIX
706 /* Some systems have a suffix for executable files.
707 So try appending that. */
708 strcat (temp
, EXECUTABLE_SUFFIX
);
710 if (stat (temp
, &st
) >= 0
711 && ! S_ISDIR (st
.st_mode
)
712 && access (temp
, X_OK
) == 0)
717 if (debug
&& pprefix
->plist
== NULL
)
718 fprintf (stderr
, " - failed: no entries in prefix list\n");
724 /* Add an entry for PREFIX to prefix list PPREFIX. */
727 add_prefix (pprefix
, prefix
)
728 struct path_prefix
*pprefix
;
731 struct prefix_list
*pl
, **prev
;
736 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
741 prev
= &pprefix
->plist
;
743 /* Keep track of the longest prefix */
745 len
= strlen (prefix
);
746 if (len
> pprefix
->max_len
)
747 pprefix
->max_len
= len
;
749 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
750 pl
->prefix
= xstrdup (prefix
);
755 pl
->next
= (struct prefix_list
*) 0;
759 /* Take the value of the environment variable ENV, break it into a path, and
760 add of the entries to PPREFIX. */
763 prefix_from_env (env
, pprefix
)
765 struct path_prefix
*pprefix
;
768 GET_ENV_PATH_LIST (p
, env
);
771 prefix_from_string (p
, pprefix
);
775 prefix_from_string (p
, pprefix
)
777 struct path_prefix
*pprefix
;
779 const char *startp
, *endp
;
780 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
783 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
788 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
790 strncpy (nstore
, startp
, endp
-startp
);
793 strcpy (nstore
, "./");
795 else if (! IS_DIR_SEPARATOR (endp
[-1]))
797 nstore
[endp
-startp
] = DIR_SEPARATOR
;
798 nstore
[endp
-startp
+1] = 0;
801 nstore
[endp
-startp
] = 0;
804 fprintf (stderr
, " - add prefix: %s\n", nstore
);
806 add_prefix (pprefix
, nstore
);
809 endp
= startp
= endp
+ 1;
818 int main
PARAMS ((int, char *[]));
824 const char *ld_suffix
= "ld";
825 const char *full_ld_suffix
= ld_suffix
;
826 const char *real_ld_suffix
= "real-ld";
827 const char *collect_ld_suffix
= "collect-ld";
828 const char *nm_suffix
= "nm";
829 const char *full_nm_suffix
= nm_suffix
;
830 const char *gnm_suffix
= "gnm";
831 const char *full_gnm_suffix
= gnm_suffix
;
833 const char *ldd_suffix
= LDD_SUFFIX
;
834 const char *full_ldd_suffix
= ldd_suffix
;
836 const char *strip_suffix
= "strip";
837 const char *full_strip_suffix
= strip_suffix
;
838 const char *gstrip_suffix
= "gstrip";
839 const char *full_gstrip_suffix
= gstrip_suffix
;
842 #ifdef COLLECT_EXPORT_LIST
845 const char *ld_file_name
;
856 int num_c_args
= argc
+9;
858 #if defined (COLLECT2_HOST_INITIALIZATION)
859 /* Perform system dependent initialization, if neccessary. */
860 COLLECT2_HOST_INITIALIZATION
;
864 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
865 receive the signal. A different setting is inheritable */
866 signal (SIGCHLD
, SIG_DFL
);
869 /* LC_CTYPE determines the character set used by the terminal so it has be set
870 to output messages correctly. */
872 #ifdef HAVE_LC_MESSAGES
873 setlocale (LC_CTYPE
, "");
874 setlocale (LC_MESSAGES
, "");
876 setlocale (LC_ALL
, "");
879 (void) bindtextdomain (PACKAGE
, localedir
);
880 (void) textdomain (PACKAGE
);
882 /* Do not invoke xcalloc before this point, since locale needs to be
883 set first, in case a diagnostic is issued. */
885 ld1
= (const char **)(ld1_argv
= (char **) xcalloc(sizeof (char *), argc
+3));
886 ld2
= (const char **)(ld2_argv
= (char **) xcalloc(sizeof (char *), argc
+10));
887 object
= (const char **)(object_lst
= (char **) xcalloc(sizeof (char *), argc
));
893 /* Parse command line early for instances of -debug. This allows
894 the debug flag to be set before functions like find_a_file()
899 for (i
= 1; argv
[i
] != NULL
; i
++)
900 if (! strcmp (argv
[i
], "-debug"))
905 #ifndef DEFAULT_A_OUT_NAME
906 output_file
= "a.out";
908 output_file
= DEFAULT_A_OUT_NAME
;
911 obstack_begin (&temporary_obstack
, 0);
912 obstack_begin (&permanent_obstack
, 0);
913 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
915 current_demangling_style
= auto_demangling
;
916 p
= getenv ("COLLECT_GCC_OPTIONS");
919 const char *q
= extract_string (&p
);
920 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
923 obstack_free (&temporary_obstack
, temporary_firstobj
);
925 /* -fno-exceptions -w */
928 c_ptr
= (const char **)
929 (c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
));
932 fatal ("no arguments");
935 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
936 signal (SIGQUIT
, handler
);
938 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
939 signal (SIGINT
, handler
);
941 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
942 signal (SIGALRM
, handler
);
945 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
946 signal (SIGHUP
, handler
);
948 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
949 signal (SIGSEGV
, handler
);
951 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
952 signal (SIGBUS
, handler
);
955 /* Extract COMPILER_PATH and PATH into our prefix list. */
956 prefix_from_env ("COMPILER_PATH", &cpath
);
957 prefix_from_env ("PATH", &path
);
960 /* If we look for a program in the compiler directories, we just use
961 the short name, since these directories are already system-specific.
962 But it we look for a program in the system directories, we need to
963 qualify the program name with the target machine. */
965 full_ld_suffix
= concat(target_machine
, "-", ld_suffix
, NULL
);
968 full_gld_suffix
= concat (target_machine
, "-", gld_suffix
, NULL
);
971 full_nm_suffix
= concat (target_machine
, "-", nm_suffix
, NULL
);
973 full_gnm_suffix
= concat (target_machine
, "-", gnm_suffix
, NULL
);
976 full_ldd_suffix
= concat (target_machine
, "-", ldd_suffix
, NULL
);
979 full_strip_suffix
= concat (target_machine
, "-", strip_suffix
, NULL
);
981 full_gstrip_suffix
= concat (target_machine
, "-", gstrip_suffix
, NULL
);
982 #endif /* CROSS_COMPILE */
984 /* Try to discover a valid linker/nm/strip to use. */
986 /* Maybe we know the right file to use (if not cross). */
988 #ifdef DEFAULT_LINKER
989 if (access (DEFAULT_LINKER
, X_OK
) == 0)
990 ld_file_name
= DEFAULT_LINKER
;
991 if (ld_file_name
== 0)
993 #ifdef REAL_LD_FILE_NAME
994 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
995 if (ld_file_name
== 0)
997 /* Search the (target-specific) compiler dirs for ld'. */
998 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
999 /* Likewise for `collect-ld'. */
1000 if (ld_file_name
== 0)
1001 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
1002 /* Search the compiler directories for `ld'. We have protection against
1003 recursive calls in find_a_file. */
1004 if (ld_file_name
== 0)
1005 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
1006 /* Search the ordinary system bin directories
1007 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1008 if (ld_file_name
== 0)
1009 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
1011 #ifdef REAL_NM_FILE_NAME
1012 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
1013 if (nm_file_name
== 0)
1015 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
1016 if (nm_file_name
== 0)
1017 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
1018 if (nm_file_name
== 0)
1019 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
1020 if (nm_file_name
== 0)
1021 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
1024 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
1025 if (ldd_file_name
== 0)
1026 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
1029 #ifdef REAL_STRIP_FILE_NAME
1030 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1031 if (strip_file_name
== 0)
1033 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1034 if (strip_file_name
== 0)
1035 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1036 if (strip_file_name
== 0)
1037 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1038 if (strip_file_name
== 0)
1039 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1041 /* Determine the full path name of the C compiler to use. */
1042 c_file_name
= getenv ("COLLECT_GCC");
1043 if (c_file_name
== 0)
1045 #ifdef CROSS_COMPILE
1046 c_file_name
= concat (target_machine
, "-gcc", NULL
);
1048 c_file_name
= "gcc";
1052 p
= find_a_file (&cpath
, c_file_name
);
1054 /* Here it should be safe to use the system search path since we should have
1055 already qualified the name of the compiler when it is needed. */
1057 p
= find_a_file (&path
, c_file_name
);
1062 *ld1
++ = *ld2
++ = ld_file_name
;
1064 /* Make temp file names. */
1065 c_file
= make_temp_file (".c");
1066 o_file
= make_temp_file (".o");
1067 #ifdef COLLECT_EXPORT_LIST
1068 export_file
= make_temp_file (".x");
1070 ldout
= make_temp_file (".ld");
1071 *c_ptr
++ = c_file_name
;
1078 #ifdef COLLECT_EXPORT_LIST
1079 /* Generate a list of directories from LIBPATH. */
1080 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1081 /* Add to this list also two standard directories where
1082 AIX loader always searches for libraries. */
1083 add_prefix (&libpath_lib_dirs
, "/lib");
1084 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1087 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1089 AIX support needs to know if -shared has been specified before
1090 parsing commandline arguments. */
1092 p
= getenv ("COLLECT_GCC_OPTIONS");
1095 const char *q
= extract_string (&p
);
1096 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1097 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1098 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1099 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1100 if (strncmp (q
, "-shared", sizeof ("-shared") - 1) == 0)
1102 if (*q
== '-' && q
[1] == 'B')
1104 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1107 q
= extract_string (&p
);
1108 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1112 obstack_free (&temporary_obstack
, temporary_firstobj
);
1113 *c_ptr
++ = "-fno-exceptions";
1116 /* !!! When GCC calls collect2,
1117 it does not know whether it is calling collect2 or ld.
1118 So collect2 cannot meaningfully understand any options
1119 except those ld understands.
1120 If you propose to make GCC pass some other option,
1121 just imagine what will happen if ld is really ld!!! */
1123 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1124 /* After the first file, put in the c++ rt0. */
1127 while ((arg
= *++argv
) != (char *) 0)
1129 *ld1
++ = *ld2
++ = arg
;
1135 #ifdef COLLECT_EXPORT_LIST
1136 /* We want to disable automatic exports on AIX when user
1137 explicitly puts an export list in command line */
1139 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1141 else if (arg
[2] == '6' && arg
[3] == '4')
1147 if (!strcmp (arg
, "-debug"))
1149 /* Already parsed. */
1158 /* place o_file BEFORE this argument! */
1164 #ifdef COLLECT_EXPORT_LIST
1166 /* Resolving full library name. */
1167 const char *s
= resolve_lib_name (arg
+2);
1169 /* Saving a full library name. */
1170 add_to_list (&libs
, s
);
1175 #ifdef COLLECT_EXPORT_LIST
1176 /* Saving directories where to search for libraries. */
1178 add_prefix (&cmdline_lib_dirs
, arg
+2);
1184 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1186 #ifdef SWITCHES_NEED_SPACES
1187 && ! strchr (SWITCHES_NEED_SPACES
, arg
[1])
1191 output_file
= &arg
[2];
1200 if (arg
[2] == '\0' && do_collecting
)
1202 /* We must strip after the nm run, otherwise C++ linking
1203 will not work. Thus we strip in the second ld run, or
1204 else with strip if there is no second ld run. */
1216 else if ((p
= strrchr (arg
, '.')) != (char *) 0
1217 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1218 || strcmp (p
, ".so") == 0 || strcmp (p
, ".lo") == 0
1219 || strcmp (p
, ".obj") == 0))
1228 /* place o_file BEFORE this argument! */
1234 if (p
[1] == 'o' || p
[1] == 'l')
1236 #ifdef COLLECT_EXPORT_LIST
1237 /* libraries can be specified directly, i.e. without -l flag. */
1240 /* Saving a full library name. */
1241 add_to_list (&libs
, arg
);
1247 #ifdef COLLECT_EXPORT_LIST
1248 /* This is added only for debugging purposes. */
1251 fprintf (stderr
, "List of libraries:\n");
1252 dump_list (stderr
, "\t", libs
.first
);
1255 /* The AIX linker will discard static constructors in object files if
1256 nothing else in the file is referenced, so look at them first. */
1258 const char **export_object_lst
= (const char **)object_lst
;
1260 while (export_object_lst
< object
)
1261 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1264 struct id
*list
= libs
.first
;
1266 for (; list
; list
= list
->next
)
1267 scan_prog_file (list
->name
, PASS_FIRST
);
1272 char *buf
= xmalloc (strlen (export_file
) + 5);
1274 sprintf (buf
, "-bE:%s", export_file
);
1278 exportf
= fopen (export_file
, "w");
1279 if (exportf
== (FILE *) 0)
1280 fatal_perror ("fopen %s", export_file
);
1281 write_aix_file (exportf
, exports
.first
);
1282 if (fclose (exportf
))
1283 fatal_perror ("fclose %s", export_file
);
1288 *c_ptr
= *ld1
= *object
= (char *) 0;
1292 notice ("collect2 version %s", version_string
);
1293 #ifdef TARGET_VERSION
1296 fprintf (stderr
, "\n");
1302 fprintf (stderr
, "ld_file_name = %s\n",
1303 (ld_file_name
? ld_file_name
: "not found"));
1304 fprintf (stderr
, "c_file_name = %s\n",
1305 (c_file_name
? c_file_name
: "not found"));
1306 fprintf (stderr
, "nm_file_name = %s\n",
1307 (nm_file_name
? nm_file_name
: "not found"));
1309 fprintf (stderr
, "ldd_file_name = %s\n",
1310 (ldd_file_name
? ldd_file_name
: "not found"));
1312 fprintf (stderr
, "strip_file_name = %s\n",
1313 (strip_file_name
? strip_file_name
: "not found"));
1314 fprintf (stderr
, "c_file = %s\n",
1315 (c_file
? c_file
: "not found"));
1316 fprintf (stderr
, "o_file = %s\n",
1317 (o_file
? o_file
: "not found"));
1319 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1321 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1323 ptr
= getenv ("COLLECT_GCC");
1325 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1327 ptr
= getenv ("COMPILER_PATH");
1329 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1331 ptr
= getenv (LIBRARY_PATH_ENV
);
1333 fprintf (stderr
, "%-20s= %s\n", LIBRARY_PATH_ENV
, ptr
);
1335 fprintf (stderr
, "\n");
1338 /* Load the program, searching all libraries and attempting to provide
1339 undefined symbols from repository information. */
1341 /* On AIX we do this later. */
1342 #ifndef COLLECT_EXPORT_LIST
1343 do_tlink (ld1_argv
, object_lst
);
1346 /* If -r or they will be run via some other method, do not build the
1347 constructor or destructor list, just return now. */
1349 #ifndef COLLECT_EXPORT_LIST
1354 #ifdef COLLECT_EXPORT_LIST
1355 /* Do the link we avoided above if we are exiting. */
1356 do_tlink (ld1_argv
, object_lst
);
1358 /* But make sure we delete the export file we may have created. */
1359 if (export_file
!= 0 && export_file
[0])
1360 maybe_unlink (export_file
);
1362 maybe_unlink (c_file
);
1363 maybe_unlink (o_file
);
1367 /* Examine the namelist with nm and search it for static constructors
1368 and destructors to call.
1369 Write the constructor and destructor tables to a .s file and reload. */
1371 /* On AIX we already scanned for global constructors/destructors. */
1372 #ifndef COLLECT_EXPORT_LIST
1373 scan_prog_file (output_file
, PASS_FIRST
);
1376 #ifdef SCAN_LIBRARIES
1377 scan_libraries (output_file
);
1382 notice ("%d constructor(s) found\n", constructors
.number
);
1383 notice ("%d destructor(s) found\n", destructors
.number
);
1384 notice ("%d frame table(s) found\n", frame_tables
.number
);
1387 if (constructors
.number
== 0 && destructors
.number
== 0
1388 && frame_tables
.number
== 0
1389 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1390 /* If we will be running these functions ourselves, we want to emit
1391 stubs into the shared library so that we do not have to relink
1392 dependent programs when we add static objects. */
1397 #ifdef COLLECT_EXPORT_LIST
1398 /* Do tlink without additional code generation */
1399 do_tlink (ld1_argv
, object_lst
);
1401 /* Strip now if it was requested on the command line. */
1404 char **real_strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1405 const char ** strip_argv
= (const char **) real_strip_argv
;
1407 strip_argv
[0] = strip_file_name
;
1408 strip_argv
[1] = output_file
;
1409 strip_argv
[2] = (char *) 0;
1410 fork_execute ("strip", real_strip_argv
);
1413 #ifdef COLLECT_EXPORT_LIST
1414 maybe_unlink (export_file
);
1416 maybe_unlink (c_file
);
1417 maybe_unlink (o_file
);
1421 /* Sort ctor and dtor lists by priority. */
1422 sort_ids (&constructors
);
1423 sort_ids (&destructors
);
1425 maybe_unlink(output_file
);
1426 outf
= fopen (c_file
, "w");
1427 if (outf
== (FILE *) 0)
1428 fatal_perror ("fopen %s", c_file
);
1430 write_c_file (outf
, c_file
);
1433 fatal_perror ("fclose %s", c_file
);
1435 /* Tell the linker that we have initializer and finalizer functions. */
1436 #ifdef LD_INIT_SWITCH
1437 #ifdef COLLECT_EXPORT_LIST
1439 /* option name + functions + colons + NULL */
1440 char *buf
= xmalloc (strlen (LD_INIT_SWITCH
)
1441 + strlen(initname
) + strlen(fininame
) + 3);
1442 sprintf (buf
, "%s:%s:%s", LD_INIT_SWITCH
, initname
, fininame
);
1446 *ld2
++ = LD_INIT_SWITCH
;
1448 *ld2
++ = LD_FINI_SWITCH
;
1453 #ifdef COLLECT_EXPORT_LIST
1456 /* If we did not add export flag to link arguments before, add it to
1457 second link phase now. No new exports should have been added. */
1458 if (! exports
.first
)
1460 char *buf
= xmalloc (strlen (export_file
) + 5);
1462 sprintf (buf
, "-bE:%s", export_file
);
1466 add_to_list (&exports
, initname
);
1467 add_to_list (&exports
, fininame
);
1468 add_to_list (&exports
, "_GLOBAL__DI");
1469 add_to_list (&exports
, "_GLOBAL__DD");
1470 exportf
= fopen (export_file
, "w");
1471 if (exportf
== (FILE *) 0)
1472 fatal_perror ("fopen %s", export_file
);
1473 write_aix_file (exportf
, exports
.first
);
1474 if (fclose (exportf
))
1475 fatal_perror ("fclose %s", export_file
);
1479 /* End of arguments to second link phase. */
1484 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1485 output_file
, c_file
);
1486 write_c_file (stderr
, "stderr");
1487 fprintf (stderr
, "========== end of c_file\n\n");
1488 #ifdef COLLECT_EXPORT_LIST
1489 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1490 write_aix_file (stderr
, exports
.first
);
1491 fprintf (stderr
, "========== end of export_file\n\n");
1495 /* Assemble the constructor and destructor tables.
1496 Link the tables in with the rest of the program. */
1498 fork_execute ("gcc", c_argv
);
1499 #ifdef COLLECT_EXPORT_LIST
1500 /* On AIX we must call tlink because of possible templates resolution */
1501 do_tlink (ld2_argv
, object_lst
);
1503 /* Otherwise, simply call ld because tlink is already done */
1504 fork_execute ("ld", ld2_argv
);
1506 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1507 constructors/destructors in shared libraries. */
1508 scan_prog_file (output_file
, PASS_SECOND
);
1511 maybe_unlink (c_file
);
1512 maybe_unlink (o_file
);
1514 #ifdef COLLECT_EXPORT_LIST
1515 maybe_unlink (export_file
);
1522 /* Wait for a process to finish, and exit if a non-zero status is found. */
1530 pwait (pexecute_pid
, &status
, 0);
1533 if (WIFSIGNALED (status
))
1535 int sig
= WTERMSIG (status
);
1536 error ("%s terminated with signal %d [%s]%s",
1537 prog
, sig
, strsignal(sig
),
1538 status
& 0200 ? "" : ", core dumped");
1539 collect_exit (FATAL_EXIT_CODE
);
1542 if (WIFEXITED (status
))
1543 return WEXITSTATUS (status
);
1552 int ret
= collect_wait (prog
);
1555 error ("%s returned %d exit status", prog
, ret
);
1561 /* Execute a program, and wait for the reply. */
1564 collect_execute (prog
, argv
, redir
)
1571 int redir_handle
= -1;
1572 int stdout_save
= -1;
1573 int stderr_save
= -1;
1581 fprintf (stderr
, "%s", argv
[0]);
1583 notice ("[cannot find %s]", prog
);
1585 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1586 fprintf (stderr
, " %s", str
);
1588 fprintf (stderr
, "\n");
1594 /* If we cannot find a program we need, complain error. Do this here
1595 since we might not end up needing something that we could not find. */
1598 fatal ("cannot find `%s'", prog
);
1602 /* Open response file. */
1603 redir_handle
= open (redir
, O_WRONLY
| O_TRUNC
| O_CREAT
);
1605 /* Duplicate the stdout and stderr file handles
1606 so they can be restored later. */
1607 stdout_save
= dup (STDOUT_FILENO
);
1608 if (stdout_save
== -1)
1609 fatal_perror ("redirecting stdout: %s", redir
);
1610 stderr_save
= dup (STDERR_FILENO
);
1611 if (stderr_save
== -1)
1612 fatal_perror ("redirecting stdout: %s", redir
);
1614 /* Redirect stdout & stderr to our response file. */
1615 dup2 (redir_handle
, STDOUT_FILENO
);
1616 dup2 (redir_handle
, STDERR_FILENO
);
1619 pexecute_pid
= pexecute (argv
[0], argv
, argv
[0], NULL
,
1620 &errmsg_fmt
, &errmsg_arg
,
1621 (PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
));
1625 /* Restore stdout and stderr to their previous settings. */
1626 dup2 (stdout_save
, STDOUT_FILENO
);
1627 dup2 (stderr_save
, STDERR_FILENO
);
1629 /* Close reponse file. */
1630 close (redir_handle
);
1633 if (pexecute_pid
== -1)
1634 fatal_perror (errmsg_fmt
, errmsg_arg
);
1638 fork_execute (prog
, argv
)
1642 collect_execute (prog
, argv
, NULL
);
1646 /* Unlink a file unless we are debugging. */
1655 notice ("[Leaving %s]\n", file
);
1659 static long sequence_number
= 0;
1661 /* Add a name to a linked list. */
1664 add_to_list (head_ptr
, name
)
1665 struct head
*head_ptr
;
1669 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1671 strcpy (newid
->name
, name
);
1673 if (head_ptr
->first
)
1674 head_ptr
->last
->next
= newid
;
1676 head_ptr
->first
= newid
;
1678 /* Check for duplicate symbols. */
1679 for (p
= head_ptr
->first
;
1680 strcmp (name
, p
->name
) != 0;
1685 head_ptr
->last
->next
= 0;
1690 newid
->sequence
= ++sequence_number
;
1691 head_ptr
->last
= newid
;
1695 /* Grab the init priority number from an init function name that
1696 looks like "_GLOBAL_.I.12345.foo". */
1699 extract_init_priority (name
)
1704 while (name
[pos
] == '_')
1706 pos
+= 10; /* strlen ("GLOBAL__X_") */
1708 /* Extract init_p number from ctor/dtor name. */
1709 pri
= atoi (name
+ pos
);
1710 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1713 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1714 ctors will be run from right to left, dtors from left to right. */
1718 struct head
*head_ptr
;
1720 /* id holds the current element to insert. id_next holds the next
1721 element to insert. id_ptr iterates through the already sorted elements
1722 looking for the place to insert id. */
1723 struct id
*id
, *id_next
, **id_ptr
;
1725 id
= head_ptr
->first
;
1727 /* We don't have any sorted elements yet. */
1728 head_ptr
->first
= NULL
;
1730 for (; id
; id
= id_next
)
1733 id
->sequence
= extract_init_priority (id
->name
);
1735 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1737 /* If the sequence numbers are the same, we put the id from the
1738 file later on the command line later in the list. */
1739 || id
->sequence
> (*id_ptr
)->sequence
1740 /* Hack: do lexical compare, too.
1741 || (id->sequence == (*id_ptr)->sequence
1742 && strcmp (id->name, (*id_ptr)->name) > 0) */
1751 /* Now set the sequence numbers properly so write_c_file works. */
1752 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1753 id
->sequence
= ++sequence_number
;
1756 /* Write: `prefix', the names on list LIST, `suffix'. */
1759 write_list (stream
, prefix
, list
)
1766 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1771 #ifdef COLLECT_EXPORT_LIST
1772 /* This function is really used only on AIX, but may be useful. */
1774 is_in_list (prefix
, list
)
1780 if (!strcmp (prefix
, list
->name
)) return 1;
1787 /* Added for debugging purpose. */
1788 #ifdef COLLECT_EXPORT_LIST
1790 dump_list (stream
, prefix
, list
)
1797 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1805 dump_prefix_list (stream
, prefix
, list
)
1808 struct prefix_list
*list
;
1812 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1819 write_list_with_asm (stream
, prefix
, list
)
1826 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1827 prefix
, list
->sequence
, list
->name
);
1832 /* Write out the constructor and destructor tables statically (for a shared
1833 object), along with the functions to execute them. */
1836 write_c_file_stat (stream
, name
)
1838 const char *name ATTRIBUTE_UNUSED
;
1842 int frames
= (frame_tables
.number
> 0);
1844 /* Figure out name of output_file, stripping off .so version. */
1845 p
= strrchr (output_file
, '/');
1861 if (strncmp (q
, ".so", 3) == 0)
1870 /* q points to null at end of the string (or . of the .so version) */
1871 prefix
= xmalloc (q
- p
+ 1);
1872 strncpy (prefix
, p
, q
- p
);
1874 for (r
= prefix
; *r
; r
++)
1875 if (!ISALNUM ((unsigned char)*r
))
1878 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1879 output_file
, prefix
);
1881 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1882 initname
= xmalloc (strlen (prefix
) + sizeof (INIT_NAME_FORMAT
) - 2);
1883 sprintf (initname
, INIT_NAME_FORMAT
, prefix
);
1885 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1886 fininame
= xmalloc (strlen (prefix
) + sizeof (FINI_NAME_FORMAT
) - 2);
1887 sprintf (fininame
, FINI_NAME_FORMAT
, prefix
);
1891 /* Write the tables as C code */
1893 fprintf (stream
, "static int count;\n");
1894 fprintf (stream
, "typedef void entry_pt();\n");
1895 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1899 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1901 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1902 write_list (stream
, "\t\t&", frame_tables
.first
);
1903 fprintf (stream
, "\t0\n};\n");
1905 /* This must match what's in frame.h. */
1906 fprintf (stream
, "struct object {\n");
1907 fprintf (stream
, " void *pc_begin;\n");
1908 fprintf (stream
, " void *pc_end;\n");
1909 fprintf (stream
, " void *fde_begin;\n");
1910 fprintf (stream
, " void *fde_array;\n");
1911 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1912 fprintf (stream
, " struct object *next;\n");
1913 fprintf (stream
, "};\n");
1915 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1916 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1918 fprintf (stream
, "static void reg_frame () {\n");
1919 fprintf (stream
, "\tstatic struct object ob;\n");
1920 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1921 fprintf (stream
, "\t}\n");
1923 fprintf (stream
, "static void dereg_frame () {\n");
1924 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1925 fprintf (stream
, "\t}\n");
1928 fprintf (stream
, "void %s() {\n", initname
);
1929 if (constructors
.number
> 0 || frames
)
1931 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1932 write_list (stream
, "\t\t", constructors
.first
);
1934 fprintf (stream
, "\treg_frame,\n");
1935 fprintf (stream
, "\t};\n");
1936 fprintf (stream
, "\tentry_pt **p;\n");
1937 fprintf (stream
, "\tif (count++ != 0) return;\n");
1938 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1939 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1942 fprintf (stream
, "\t++count;\n");
1943 fprintf (stream
, "}\n");
1944 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1945 fprintf (stream
, "void %s() {\n", fininame
);
1946 if (destructors
.number
> 0 || frames
)
1948 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1949 write_list (stream
, "\t\t", destructors
.first
);
1951 fprintf (stream
, "\tdereg_frame,\n");
1952 fprintf (stream
, "\t};\n");
1953 fprintf (stream
, "\tentry_pt **p;\n");
1954 fprintf (stream
, "\tif (--count != 0) return;\n");
1955 fprintf (stream
, "\tp = dtors;\n");
1956 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
1957 destructors
.number
+ frames
);
1959 fprintf (stream
, "}\n");
1963 fprintf (stream
, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname
);
1964 fprintf (stream
, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame
);
1968 /* Write the constructor/destructor tables. */
1970 #ifndef LD_INIT_SWITCH
1972 write_c_file_glob (stream
, name
)
1974 const char *name ATTRIBUTE_UNUSED
;
1976 /* Write the tables as C code */
1978 int frames
= (frame_tables
.number
> 0);
1980 fprintf (stream
, "typedef void entry_pt();\n\n");
1982 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1986 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1988 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1989 write_list (stream
, "\t\t&", frame_tables
.first
);
1990 fprintf (stream
, "\t0\n};\n");
1992 /* This must match what's in frame.h. */
1993 fprintf (stream
, "struct object {\n");
1994 fprintf (stream
, " void *pc_begin;\n");
1995 fprintf (stream
, " void *pc_end;\n");
1996 fprintf (stream
, " void *fde_begin;\n");
1997 fprintf (stream
, " void *fde_array;\n");
1998 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1999 fprintf (stream
, " struct object *next;\n");
2000 fprintf (stream
, "};\n");
2002 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2003 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2005 fprintf (stream
, "static void reg_frame () {\n");
2006 fprintf (stream
, "\tstatic struct object ob;\n");
2007 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2008 fprintf (stream
, "\t}\n");
2010 fprintf (stream
, "static void dereg_frame () {\n");
2011 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2012 fprintf (stream
, "\t}\n");
2015 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2016 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2017 write_list (stream
, "\t", constructors
.first
);
2019 fprintf (stream
, "\treg_frame,\n");
2020 fprintf (stream
, "\t0\n};\n\n");
2022 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2024 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2025 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2026 write_list (stream
, "\t", destructors
.first
);
2028 fprintf (stream
, "\tdereg_frame,\n");
2029 fprintf (stream
, "\t0\n};\n\n");
2031 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2032 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2034 #endif /* ! LD_INIT_SWITCH */
2037 write_c_file (stream
, name
)
2041 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2042 #ifndef LD_INIT_SWITCH
2044 write_c_file_glob (stream
, name
);
2047 write_c_file_stat (stream
, name
);
2048 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2051 #ifdef COLLECT_EXPORT_LIST
2053 write_aix_file (stream
, list
)
2057 for (; list
; list
= list
->next
)
2059 fputs (list
->name
, stream
);
2060 putc ('\n', stream
);
2065 #ifdef OBJECT_FORMAT_NONE
2067 /* Generic version to scan the name list of the loaded program for
2068 the symbols g++ uses for static constructors and destructors.
2070 The constructor table begins at __CTOR_LIST__ and contains a count
2071 of the number of pointers (or -1 if the constructors are built in a
2072 separate section by the linker), followed by the pointers to the
2073 constructor functions, terminated with a null pointer. The
2074 destructor table has the same format, and begins at __DTOR_LIST__. */
2077 scan_prog_file (prog_name
, which_pass
)
2078 const char *prog_name
;
2079 enum pass which_pass
;
2081 void (*int_handler
) PARAMS ((int));
2082 void (*quit_handler
) PARAMS ((int));
2083 char *real_nm_argv
[4];
2084 const char **nm_argv
= (const char **) real_nm_argv
;
2091 if (which_pass
== PASS_SECOND
)
2094 /* If we do not have an `nm', complain. */
2095 if (nm_file_name
== 0)
2096 fatal ("cannot find `nm'");
2098 nm_argv
[argc
++] = nm_file_name
;
2099 if (NM_FLAGS
[0] != '\0')
2100 nm_argv
[argc
++] = NM_FLAGS
;
2102 nm_argv
[argc
++] = prog_name
;
2103 nm_argv
[argc
++] = (char *) 0;
2105 if (pipe (pipe_fd
) < 0)
2106 fatal_perror ("pipe");
2108 inf
= fdopen (pipe_fd
[0], "r");
2109 if (inf
== (FILE *) 0)
2110 fatal_perror ("fdopen");
2112 /* Trace if needed. */
2115 const char **p_argv
;
2118 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2119 fprintf (stderr
, " %s", str
);
2121 fprintf (stderr
, "\n");
2127 /* Spawn child nm on pipe */
2130 fatal_perror (VFORK_STRING
);
2132 if (pid
== 0) /* child context */
2135 if (dup2 (pipe_fd
[1], 1) < 0)
2136 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2138 if (close (pipe_fd
[0]) < 0)
2139 fatal_perror ("close %d", pipe_fd
[0]);
2141 if (close (pipe_fd
[1]) < 0)
2142 fatal_perror ("close %d", pipe_fd
[1]);
2144 execv (nm_file_name
, real_nm_argv
);
2145 fatal_perror ("execvp %s", nm_file_name
);
2148 /* Parent context from here on. */
2149 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2151 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2154 if (close (pipe_fd
[1]) < 0)
2155 fatal_perror ("close %d", pipe_fd
[1]);
2158 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2160 /* Read each line of nm output. */
2161 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2166 /* If it contains a constructor or destructor name, add the name
2167 to the appropriate list. */
2169 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2170 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2177 /* Find the end of the symbol name.
2178 Do not include `|', because Encore nm can tack that on the end. */
2179 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2185 switch (is_ctor_dtor (name
))
2188 if (which_pass
!= PASS_LIB
)
2189 add_to_list (&constructors
, name
);
2193 if (which_pass
!= PASS_LIB
)
2194 add_to_list (&destructors
, name
);
2198 if (which_pass
!= PASS_LIB
)
2199 fatal ("init function found in object %s", prog_name
);
2200 #ifndef LD_INIT_SWITCH
2201 add_to_list (&constructors
, name
);
2206 if (which_pass
!= PASS_LIB
)
2207 fatal ("fini function found in object %s", prog_name
);
2208 #ifndef LD_FINI_SWITCH
2209 add_to_list (&destructors
, name
);
2214 if (which_pass
!= PASS_LIB
)
2215 add_to_list (&frame_tables
, name
);
2218 default: /* not a constructor or destructor */
2223 fprintf (stderr
, "\t%s\n", buf
);
2227 fprintf (stderr
, "\n");
2229 if (fclose (inf
) != 0)
2230 fatal_perror ("fclose");
2232 do_wait (nm_file_name
);
2234 signal (SIGINT
, int_handler
);
2236 signal (SIGQUIT
, quit_handler
);
2240 #if SUNOS4_SHARED_LIBRARIES
2242 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2243 that the output file depends upon and their initialization/finalization
2244 routines, if any. */
2249 #include <sys/mman.h>
2250 #include <sys/param.h>
2252 #include <sys/dir.h>
2254 /* pointers to the object file */
2255 unsigned object
; /* address of memory mapped file */
2256 unsigned objsize
; /* size of memory mapped to file */
2257 char * code
; /* pointer to code segment */
2258 char * data
; /* pointer to data segment */
2259 struct nlist
*symtab
; /* pointer to symbol table */
2260 struct link_dynamic
*ld
;
2261 struct link_dynamic_2
*ld_2
;
2262 struct head libraries
;
2264 /* Map the file indicated by NAME into memory and store its address. */
2266 static void mapfile
PARAMS ((const char *));
2274 if ((fp
= open (name
, O_RDONLY
)) == -1)
2275 fatal ("unable to open file '%s'", name
);
2276 if (fstat (fp
, &s
) == -1)
2277 fatal ("unable to stat file '%s'", name
);
2279 objsize
= s
.st_size
;
2280 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2282 if (object
== (unsigned)-1)
2283 fatal ("unable to mmap file '%s'", name
);
2288 /* Helpers for locatelib. */
2290 static const char *libname
;
2292 static int libselect
PARAMS ((struct direct
*));
2298 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2301 /* If one file has an additional numeric extension past LIBNAME, then put
2302 that one first in the sort. If both files have additional numeric
2303 extensions, then put the one with the higher number first in the sort.
2305 We must verify that the extension is numeric, because Sun saves the
2306 original versions of patched libraries with a .FCS extension. Files with
2307 invalid extensions must go last in the sort, so that they will not be used. */
2308 static int libcompare
PARAMS ((struct direct
**, struct direct
**));
2312 struct direct
**d1
, **d2
;
2314 int i1
, i2
= strlen (libname
);
2315 char *e1
= (*d1
)->d_name
+ i2
;
2316 char *e2
= (*d2
)->d_name
+ i2
;
2318 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2319 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2323 i1
= strtol (e1
, &e1
, 10);
2324 i2
= strtol (e2
, &e2
, 10);
2331 /* It has a valid numeric extension, prefer this one. */
2332 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2334 /* It has a invalid numeric extension, must prefer the other one. */
2340 /* It has a valid numeric extension, prefer this one. */
2341 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2343 /* It has a invalid numeric extension, must prefer the other one. */
2351 /* Given the name NAME of a dynamic dependency, find its pathname and add
2352 it to the list of libraries. */
2353 static void locatelib
PARAMS ((const char *));
2359 static const char **l
;
2361 char buf
[MAXPATHLEN
];
2369 /* counting elements in array, need 1 extra for null */
2371 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2375 for (; *ld_rules
!= 0; ld_rules
++)
2376 if (*ld_rules
== ':')
2378 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2379 ldr
= xstrdup (ld_rules
);
2381 p
= getenv ("LD_LIBRARY_PATH");
2386 for (q
= p
; *q
!= 0; q
++)
2391 l
= (const char **) xmalloc ((cnt
+ 3) * sizeof (char *));
2396 for (; *ldr
!= 0; ldr
++)
2406 for (; *q
!= 0; q
++)
2413 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2416 *pp
++ = "/usr/local/lib";
2420 for (pp
= l
; *pp
!= 0 ; pp
++)
2422 struct direct
**namelist
;
2424 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2426 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2427 add_to_list (&libraries
, buf
);
2429 fprintf (stderr
, "%s\n", buf
);
2436 notice ("not found\n");
2438 fatal ("dynamic dependency %s not found", name
);
2442 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2443 that it depends upon and any constructors or destructors they contain. */
2446 scan_libraries (prog_name
)
2447 const char *prog_name
;
2449 struct exec
*header
;
2451 struct link_object
*lo
;
2452 char buff
[MAXPATHLEN
];
2455 mapfile (prog_name
);
2456 header
= (struct exec
*)object
;
2457 if (N_BADMAG (*header
))
2458 fatal ("bad magic number in file '%s'", prog_name
);
2459 if (header
->a_dynamic
== 0)
2462 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2463 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2464 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2466 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2469 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2475 ld
= (struct link_dynamic
*) data
;
2480 notice ("dynamic dependencies.\n");
2482 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2483 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2484 lo
= (struct link_object
*) lo
->lo_next
)
2487 lo
= (struct link_object
*) ((long) lo
+ code
);
2488 name
= (char *) (code
+ lo
->lo_name
);
2492 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2493 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2499 fprintf (stderr
, "\t%s\n", name
);
2500 add_to_list (&libraries
, name
);
2505 fprintf (stderr
, "\n");
2507 /* now iterate through the library list adding their symbols to
2509 for (list
= libraries
.first
; list
; list
= list
->next
)
2510 scan_prog_file (list
->name
, PASS_LIB
);
2513 #else /* SUNOS4_SHARED_LIBRARIES */
2516 /* Use the List Dynamic Dependencies program to find shared libraries that
2517 the output file depends upon and their initialization/finalization
2518 routines, if any. */
2521 scan_libraries (prog_name
)
2522 const char *prog_name
;
2524 static struct head libraries
; /* list of shared libraries found */
2526 void (*int_handler
) PARAMS ((int));
2527 void (*quit_handler
) PARAMS ((int));
2528 char *real_ldd_argv
[4];
2529 const char **ldd_argv
= (const char **) real_ldd_argv
;
2536 /* If we do not have an `ldd', complain. */
2537 if (ldd_file_name
== 0)
2539 error ("cannot find `ldd'");
2543 ldd_argv
[argc
++] = ldd_file_name
;
2544 ldd_argv
[argc
++] = prog_name
;
2545 ldd_argv
[argc
++] = (char *) 0;
2547 if (pipe (pipe_fd
) < 0)
2548 fatal_perror ("pipe");
2550 inf
= fdopen (pipe_fd
[0], "r");
2551 if (inf
== (FILE *) 0)
2552 fatal_perror ("fdopen");
2554 /* Trace if needed. */
2557 const char **p_argv
;
2560 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2561 fprintf (stderr
, " %s", str
);
2563 fprintf (stderr
, "\n");
2569 /* Spawn child ldd on pipe */
2572 fatal_perror (VFORK_STRING
);
2574 if (pid
== 0) /* child context */
2577 if (dup2 (pipe_fd
[1], 1) < 0)
2578 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2580 if (close (pipe_fd
[0]) < 0)
2581 fatal_perror ("close %d", pipe_fd
[0]);
2583 if (close (pipe_fd
[1]) < 0)
2584 fatal_perror ("close %d", pipe_fd
[1]);
2586 execv (ldd_file_name
, real_ldd_argv
);
2587 fatal_perror ("execv %s", ldd_file_name
);
2590 /* Parent context from here on. */
2591 int_handler
= (void (*) PARAMS ((int))) signal (SIGINT
, SIG_IGN
);
2593 quit_handler
= (void (*) PARAMS ((int))) signal (SIGQUIT
, SIG_IGN
);
2596 if (close (pipe_fd
[1]) < 0)
2597 fatal_perror ("close %d", pipe_fd
[1]);
2600 notice ("\nldd output with constructors/destructors.\n");
2602 /* Read each line of ldd output. */
2603 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2606 char *name
, *end
, *p
= buf
;
2608 /* Extract names of libraries and add to list. */
2609 PARSE_LDD_OUTPUT (p
);
2614 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2615 fatal ("dynamic dependency %s not found", buf
);
2617 /* Find the end of the symbol name. */
2619 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2624 if (access (name
, R_OK
) == 0)
2625 add_to_list (&libraries
, name
);
2627 fatal ("unable to open dynamic dependency '%s'", buf
);
2630 fprintf (stderr
, "\t%s\n", buf
);
2633 fprintf (stderr
, "\n");
2635 if (fclose (inf
) != 0)
2636 fatal_perror ("fclose");
2638 do_wait (ldd_file_name
);
2640 signal (SIGINT
, int_handler
);
2642 signal (SIGQUIT
, quit_handler
);
2645 /* now iterate through the library list adding their symbols to
2647 for (list
= libraries
.first
; list
; list
= list
->next
)
2648 scan_prog_file (list
->name
, PASS_LIB
);
2651 #endif /* LDD_SUFFIX */
2652 #endif /* SUNOS4_SHARED_LIBRARIES */
2654 #endif /* OBJECT_FORMAT_NONE */
2658 * COFF specific stuff.
2661 #ifdef OBJECT_FORMAT_COFF
2663 #if defined(EXTENDED_COFF)
2665 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2666 # define GCC_SYMENT SYMR
2667 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2668 # define GCC_SYMINC(X) (1)
2669 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2670 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2674 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2675 # define GCC_SYMENT SYMENT
2676 # define GCC_OK_SYMBOL(X) \
2677 (((X).n_sclass == C_EXT) && \
2678 ((X).n_scnum > N_UNDEF) && \
2680 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2681 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2682 # define GCC_UNDEF_SYMBOL(X) \
2683 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2684 # define GCC_SYMINC(X) ((X).n_numaux+1)
2685 # define GCC_SYMZERO(X) 0
2687 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2689 # define GCC_CHECK_HDR(X) \
2690 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2691 || (HEADER (X).f_magic == 0767 && aix64_flag))
2693 # define GCC_CHECK_HDR(X) \
2694 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2695 || (HEADER (X).f_magic == 0757 && aix64_flag))
2700 extern char *ldgetname ();
2702 /* COFF version to scan the name list of the loaded program for
2703 the symbols g++ uses for static constructors and destructors.
2705 The constructor table begins at __CTOR_LIST__ and contains a count
2706 of the number of pointers (or -1 if the constructors are built in a
2707 separate section by the linker), followed by the pointers to the
2708 constructor functions, terminated with a null pointer. The
2709 destructor table has the same format, and begins at __DTOR_LIST__. */
2712 scan_prog_file (prog_name
, which_pass
)
2713 const char *prog_name
;
2714 enum pass which_pass
;
2716 LDFILE
*ldptr
= NULL
;
2717 int sym_index
, sym_count
;
2720 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2723 #ifdef COLLECT_EXPORT_LIST
2724 /* We do not need scanning for some standard C libraries. */
2725 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2728 /* On AIX we have a loop, because there is not much difference
2729 between an object and an archive. This trick allows us to
2730 eliminate scan_libraries() function. */
2734 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2735 non-const char * filename parameter, even though it will not
2736 modify that string. So we must cast away const-ness here,
2737 which will cause -Wcast-qual to burp. */
2738 if ((ldptr
= ldopen ((char *)prog_name
, ldptr
)) != NULL
)
2740 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2741 fatal ("%s: not a COFF file", prog_name
);
2743 if (GCC_CHECK_HDR (ldptr
))
2745 sym_count
= GCC_SYMBOLS (ldptr
);
2746 sym_index
= GCC_SYMZERO (ldptr
);
2748 #ifdef COLLECT_EXPORT_LIST
2749 /* Is current archive member a shared object? */
2750 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2753 while (sym_index
< sym_count
)
2757 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2759 sym_index
+= GCC_SYMINC (symbol
);
2761 if (GCC_OK_SYMBOL (symbol
))
2765 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2766 continue; /* should never happen */
2768 #ifdef XCOFF_DEBUGGING_INFO
2769 /* All AIX function names have a duplicate entry
2770 beginning with a dot. */
2775 switch (is_ctor_dtor (name
))
2779 add_to_list (&constructors
, name
);
2780 #ifdef COLLECT_EXPORT_LIST
2781 if (which_pass
== PASS_OBJ
)
2782 add_to_list (&exports
, name
);
2788 add_to_list (&destructors
, name
);
2789 #ifdef COLLECT_EXPORT_LIST
2790 if (which_pass
== PASS_OBJ
)
2791 add_to_list (&exports
, name
);
2795 #ifdef COLLECT_EXPORT_LIST
2797 #ifndef LD_INIT_SWITCH
2799 add_to_list (&constructors
, name
);
2804 #ifndef LD_INIT_SWITCH
2806 add_to_list (&destructors
, name
);
2813 add_to_list (&frame_tables
, name
);
2814 #ifdef COLLECT_EXPORT_LIST
2815 if (which_pass
== PASS_OBJ
)
2816 add_to_list (&exports
, name
);
2820 default: /* not a constructor or destructor */
2821 #ifdef COLLECT_EXPORT_LIST
2822 /* If we are building a shared object on AIX we need
2823 to explicitly export all global symbols. */
2826 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2827 add_to_list (&exports
, name
);
2834 #if !defined(EXTENDED_COFF)
2835 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2836 symbol
.n_scnum
, symbol
.n_sclass
,
2837 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2841 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2842 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2847 #ifdef COLLECT_EXPORT_LIST
2850 /* If archive contains both 32-bit and 64-bit objects,
2851 we want to skip objects in other mode so mismatch normal. */
2853 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2854 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2860 fatal ("%s: cannot open as COFF file", prog_name
);
2862 #ifdef COLLECT_EXPORT_LIST
2863 /* On AIX loop continues while there are more members in archive. */
2865 while (ldclose (ldptr
) == FAILURE
);
2867 /* Otherwise we simply close ldptr. */
2868 (void) ldclose(ldptr
);
2873 #ifdef COLLECT_EXPORT_LIST
2874 /* Given a library name without "lib" prefix, this function
2875 returns a full library name including a path. */
2877 resolve_lib_name (name
)
2883 for (i
= 0; libpaths
[i
]; i
++)
2884 if (libpaths
[i
]->max_len
> l
)
2885 l
= libpaths
[i
]->max_len
;
2887 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2889 for (i
= 0; libpaths
[i
]; i
++)
2891 struct prefix_list
*list
= libpaths
[i
]->plist
;
2892 for (; list
; list
= list
->next
)
2894 /* The following lines are needed because path_prefix list
2895 may contain directories both with trailing '/' and
2898 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
2900 for (j
= 0; libexts
[j
]; j
++)
2902 sprintf (lib_buf
, "%s%slib%s.%s",
2903 list
->prefix
, p
, name
, libexts
[j
]);
2904 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
2905 if (file_exists (lib_buf
))
2907 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
2914 fprintf (stderr
, "not found\n");
2916 fatal ("Library lib%s not found", name
);
2920 /* Array of standard AIX libraries which should not
2921 be scanned for ctors/dtors. */
2922 static const char *aix_std_libs
[] = {
2930 "/usr/lib/libc_r.a",
2931 "/usr/lib/libm_r.a",
2932 "/usr/lib/threads/libc.a",
2933 "/usr/ccs/lib/libc.a",
2934 "/usr/ccs/lib/libm.a",
2935 "/usr/ccs/lib/libc_r.a",
2936 "/usr/ccs/lib/libm_r.a",
2940 /* This function checks the filename and returns 1
2941 if this name matches the location of a standard AIX library. */
2943 ignore_library (name
)
2946 const char **p
= &aix_std_libs
[0];
2947 while (*p
++ != NULL
)
2948 if (! strcmp (name
, *p
)) return 1;
2953 #endif /* OBJECT_FORMAT_COFF */
2957 * OSF/rose specific stuff.
2960 #ifdef OBJECT_FORMAT_ROSE
2962 /* Union of the various load commands */
2964 typedef union load_union
2966 ldc_header_t hdr
; /* common header */
2967 load_cmd_map_command_t map
; /* map indexing other load cmds */
2968 interpreter_command_t iprtr
; /* interpreter pathname */
2969 strings_command_t str
; /* load commands strings section */
2970 region_command_t region
; /* region load command */
2971 reloc_command_t reloc
; /* relocation section */
2972 package_command_t pkg
; /* package load command */
2973 symbols_command_t sym
; /* symbol sections */
2974 entry_command_t ent
; /* program start section */
2975 gen_info_command_t info
; /* object information */
2976 func_table_command_t func
; /* function constructors/destructors */
2979 /* Structure to point to load command and data section in memory. */
2981 typedef struct load_all
2983 load_union_t
*load
; /* load command */
2984 char *section
; /* pointer to section */
2987 /* Structure to contain information about a file mapped into memory. */
2991 char *start
; /* start of map */
2992 char *name
; /* filename */
2993 long size
; /* size of the file */
2994 long rounded_size
; /* size rounded to page boundary */
2995 int fd
; /* file descriptor */
2996 int rw
; /* != 0 if opened read/write */
2997 int use_mmap
; /* != 0 if mmap'ed */
3000 extern int decode_mach_o_hdr ();
3001 extern int encode_mach_o_hdr ();
3003 static void add_func_table
PARAMS ((mo_header_t
*, load_all_t
*,
3004 symbol_info_t
*, int));
3005 static void print_header
PARAMS ((mo_header_t
*));
3006 static void print_load_command
PARAMS ((load_union_t
*, size_t, int));
3007 static void bad_header
PARAMS ((int));
3008 static struct file_info
*read_file
PARAMS ((const char *, int, int));
3009 static void end_file
PARAMS ((struct file_info
*));
3011 /* OSF/rose specific version to scan the name list of the loaded
3012 program for the symbols g++ uses for static constructors and
3015 The constructor table begins at __CTOR_LIST__ and contains a count
3016 of the number of pointers (or -1 if the constructors are built in a
3017 separate section by the linker), followed by the pointers to the
3018 constructor functions, terminated with a null pointer. The
3019 destructor table has the same format, and begins at __DTOR_LIST__. */
3022 scan_prog_file (prog_name
, which_pass
)
3023 const char *prog_name
;
3024 enum pass which_pass
;
3028 load_all_t
*load_array
;
3029 load_all_t
*load_end
;
3030 load_all_t
*load_cmd
;
3031 int symbol_load_cmds
;
3037 struct file_info
*obj_file
;
3039 mo_lcid_t cmd_strings
= -1;
3040 symbol_info_t
*main_sym
= 0;
3041 int rw
= (which_pass
!= PASS_FIRST
);
3043 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3045 fatal_perror ("open %s", prog_name
);
3047 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3048 obj
= obj_file
->start
;
3050 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3051 if (status
!= MO_HDR_CONV_SUCCESS
)
3052 bad_header (status
);
3055 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3056 since the hardware will automatically swap bytes for us on loading little endian
3059 #ifndef CROSS_COMPILE
3060 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3061 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3062 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3063 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3064 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3065 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3066 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3068 fatal ("incompatibilities between object file & expected values");
3073 print_header (&hdr
);
3075 offset
= hdr
.moh_first_cmd_off
;
3076 load_end
= load_array
3077 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3079 /* Build array of load commands, calculating the offsets */
3080 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3082 load_union_t
*load_hdr
; /* load command header */
3084 load_cmd
= load_end
++;
3085 load_hdr
= (load_union_t
*) (obj
+ offset
);
3087 /* If modifying the program file, copy the header. */
3090 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3091 memcpy ((char *)ptr
, (char *)load_hdr
, load_hdr
->hdr
.ldci_cmd_size
);
3094 /* null out old command map, because we will rewrite at the end. */
3095 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3097 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3098 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3102 load_cmd
->load
= load_hdr
;
3103 if (load_hdr
->hdr
.ldci_section_off
> 0)
3104 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3107 print_load_command (load_hdr
, offset
, i
);
3109 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3112 /* If the last command is the load command map and is not undefined,
3113 decrement the count of load commands. */
3114 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3117 hdr
.moh_n_load_cmds
--;
3120 /* Go through and process each symbol table section. */
3121 symbol_load_cmds
= 0;
3122 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3124 load_union_t
*load_hdr
= load_cmd
->load
;
3126 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3132 const char *kind
= "unknown";
3134 switch (load_hdr
->sym
.symc_kind
)
3136 case SYMC_IMPORTS
: kind
= "imports"; break;
3137 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3138 case SYMC_STABS
: kind
= "stabs"; break;
3141 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3142 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3145 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3148 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3149 if (str_sect
== (char *) 0)
3150 fatal ("string section missing");
3152 if (load_cmd
->section
== (char *) 0)
3153 fatal ("section pointer missing");
3155 num_syms
= load_hdr
->sym
.symc_nentries
;
3156 for (i
= 0; i
< num_syms
; i
++)
3158 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3159 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3166 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3168 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3178 switch (is_ctor_dtor (name
))
3181 add_to_list (&constructors
, name
);
3185 add_to_list (&destructors
, name
);
3188 default: /* not a constructor or destructor */
3194 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3195 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3200 if (symbol_load_cmds
== 0)
3201 fatal ("no symbol table found");
3203 /* Update the program file now, rewrite header and load commands. At present,
3204 we assume that there is enough space after the last load command to insert
3205 one more. Since the first section written out is page aligned, and the
3206 number of load commands is small, this is ok for the present. */
3210 load_union_t
*load_map
;
3213 if (cmd_strings
== -1)
3214 fatal ("no cmd_strings found");
3216 /* Add __main to initializer list.
3217 If we are building a program instead of a shared library, do not
3218 do anything, since in the current version, you cannot do mallocs
3219 and such in the constructors. */
3221 if (main_sym
!= (symbol_info_t
*) 0
3222 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3223 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3226 notice ("\nUpdating header and load commands.\n\n");
3228 hdr
.moh_n_load_cmds
++;
3229 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3231 /* Create new load command map. */
3233 notice ("load command map, %d cmds, new size %ld.\n",
3234 (int) hdr
.moh_n_load_cmds
, (long) size
);
3236 load_map
= (load_union_t
*) xcalloc (1, size
);
3237 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3238 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3239 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3240 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3241 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3243 offset
= hdr
.moh_first_cmd_off
;
3244 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3246 load_map
->map
.lcm_map
[i
] = offset
;
3247 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3248 hdr
.moh_load_map_cmd_off
= offset
;
3250 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3253 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3256 print_header (&hdr
);
3259 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3260 if (status
!= MO_HDR_CONV_SUCCESS
)
3261 bad_header (status
);
3264 notice ("writing load commands.\n\n");
3266 /* Write load commands */
3267 offset
= hdr
.moh_first_cmd_off
;
3268 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3270 load_union_t
*load_hdr
= load_array
[i
].load
;
3271 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3274 print_load_command (load_hdr
, offset
, i
);
3276 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3281 end_file (obj_file
);
3283 if (close (prog_fd
))
3284 fatal_perror ("close %s", prog_name
);
3287 fprintf (stderr
, "\n");
3291 /* Add a function table to the load commands to call a function
3292 on initiation or termination of the process. */
3295 add_func_table (hdr_p
, load_array
, sym
, type
)
3296 mo_header_t
*hdr_p
; /* pointer to global header */
3297 load_all_t
*load_array
; /* array of ptrs to load cmds */
3298 symbol_info_t
*sym
; /* pointer to symbol entry */
3299 int type
; /* fntc_type value */
3301 /* Add a new load command. */
3302 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3303 int load_index
= num_cmds
- 1;
3304 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3305 load_union_t
*ptr
= xcalloc (1, size
);
3306 load_all_t
*load_cmd
;
3309 /* Set the unresolved address bit in the header to force the loader to be
3310 used, since kernel exec does not call the initialization functions. */
3311 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3313 load_cmd
= &load_array
[load_index
];
3314 load_cmd
->load
= ptr
;
3315 load_cmd
->section
= (char *) 0;
3317 /* Fill in func table load command. */
3318 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3319 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3320 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3321 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3322 ptr
->func
.fntc_type
= type
;
3323 ptr
->func
.fntc_nentries
= 1;
3325 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3326 /* Is the symbol already expressed as (region, offset)? */
3327 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3329 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3330 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3333 /* If not, figure out which region it's in. */
3336 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3339 for (i
= 0; i
< load_index
; i
++)
3341 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3343 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3345 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3346 && addr
>= region_ptr
->regc_addr
.vm_addr
3347 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3349 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3350 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3358 fatal ("could not convert 0x%l.8x into a region", addr
);
3362 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3363 type
== FNTC_INITIALIZATION
? "init" : "term",
3364 (int) ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3365 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3366 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3371 /* Print the global header for an OSF/rose object. */
3374 print_header (hdr_ptr
)
3375 mo_header_t
*hdr_ptr
;
3377 fprintf (stderr
, "\nglobal header:\n");
3378 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3379 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3380 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3381 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3382 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3383 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3384 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3385 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3386 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3387 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3388 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3389 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3390 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3391 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3392 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3394 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3395 fprintf (stderr
, ", relocatable");
3397 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3398 fprintf (stderr
, ", linkable");
3400 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3401 fprintf (stderr
, ", execable");
3403 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3404 fprintf (stderr
, ", executable");
3406 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3407 fprintf (stderr
, ", unresolved");
3409 fprintf (stderr
, "\n\n");
3414 /* Print a short summary of a load command. */
3417 print_load_command (load_hdr
, offset
, number
)
3418 load_union_t
*load_hdr
;
3422 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3423 const char *type_str
= (char *) 0;
3427 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3428 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3429 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3430 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3431 case LDC_REGION
: type_str
= "REGION"; break;
3432 case LDC_RELOC
: type_str
= "RELOC"; break;
3433 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3434 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3435 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3436 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3437 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3441 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3443 (long) load_hdr
->hdr
.ldci_cmd_size
,
3445 (long) load_hdr
->hdr
.ldci_section_off
,
3446 (long) load_hdr
->hdr
.ldci_section_len
);
3448 if (type_str
== (char *) 0)
3449 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3451 else if (type
!= LDC_REGION
)
3452 fprintf (stderr
, ", ty: %s\n", type_str
);
3456 const char *region
= "";
3457 switch (load_hdr
->region
.regc_usage_type
)
3459 case REG_TEXT_T
: region
= ", .text"; break;
3460 case REG_DATA_T
: region
= ", .data"; break;
3461 case REG_BSS_T
: region
= ", .bss"; break;
3462 case REG_GLUE_T
: region
= ", .glue"; break;
3463 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3464 case REG_RDATA_T
: region
= ", .rdata"; break;
3465 case REG_SDATA_T
: region
= ", .sdata"; break;
3466 case REG_SBSS_T
: region
= ", .sbss"; break;
3470 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3472 (long) load_hdr
->region
.regc_vm_addr
,
3473 (long) load_hdr
->region
.regc_vm_size
,
3481 /* Fatal error when {en,de}code_mach_o_header fails. */
3489 case MO_ERROR_BAD_MAGIC
: fatal ("bad magic number");
3490 case MO_ERROR_BAD_HDR_VERS
: fatal ("bad header version");
3491 case MO_ERROR_BAD_RAW_HDR_VERS
: fatal ("bad raw header version");
3492 case MO_ERROR_BUF2SML
: fatal ("raw header buffer too small");
3493 case MO_ERROR_OLD_RAW_HDR_FILE
: fatal ("old raw header file");
3494 case MO_ERROR_UNSUPPORTED_VERS
: fatal ("unsupported version");
3496 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3501 /* Read a file into a memory buffer. */
3503 static struct file_info
*
3504 read_file (name
, fd
, rw
)
3505 const char *name
; /* filename */
3506 int fd
; /* file descriptor */
3507 int rw
; /* read/write */
3509 struct stat stat_pkt
;
3510 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3512 static int page_size
;
3515 if (fstat (fd
, &stat_pkt
) < 0)
3516 fatal_perror ("fstat %s", name
);
3519 p
->size
= stat_pkt
.st_size
;
3520 p
->rounded_size
= stat_pkt
.st_size
;
3526 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3529 page_size
= sysconf (_SC_PAGE_SIZE
);
3531 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3532 p
->start
= mmap ((caddr_t
) 0,
3533 (rw
) ? p
->rounded_size
: p
->size
,
3534 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3535 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3539 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3543 #endif /* USE_MMAP */
3548 fprintf (stderr
, "read %s\n", name
);
3551 p
->start
= xmalloc (p
->size
);
3552 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3553 fatal_perror ("lseek %s 0", name
);
3555 len
= read (fd
, p
->start
, p
->size
);
3557 fatal_perror ("read %s", name
);
3560 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3566 /* Do anything necessary to write a file back from memory. */
3570 struct file_info
*ptr
; /* file information block */
3578 fprintf (stderr
, "msync %s\n", ptr
->name
);
3580 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3581 fatal_perror ("msync %s", ptr
->name
);
3585 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3587 if (munmap (ptr
->start
, ptr
->size
))
3588 fatal_perror ("munmap %s", ptr
->name
);
3591 #endif /* USE_MMAP */
3598 fprintf (stderr
, "write %s\n", ptr
->name
);
3600 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3601 fatal_perror ("lseek %s 0", ptr
->name
);
3603 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3605 fatal_perror ("write %s", ptr
->name
);
3607 if (len
!= ptr
->size
)
3608 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3617 #endif /* OBJECT_FORMAT_ROSE */