1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
4 Contributed by Chris Smith (csmith@convex.com).
5 Heavily modified by Michael Meissner (meissner@cygnus.com),
6 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
26 /* Build tables of static constructors and destructors and run ld. */
32 #ifdef vfork /* Autoconf may define this to fork for us. */
33 # define VFORK_STRING "fork"
35 # define VFORK_STRING "vfork"
41 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
42 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
52 /* Obstack allocation and deallocation routines. */
53 #define obstack_chunk_alloc xmalloc
54 #define obstack_chunk_free free
56 extern char *make_temp_file
PROTO ((const char *));
58 /* On certain systems, we have code that works by scanning the object file
59 directly. But this code uses system-specific header files and library
60 functions, so turn it off in a cross-compiler. Likewise, the names of
61 the utilities are not correct for a cross-compiler; we have to hope that
62 cross-versions are in the proper directories. */
65 #undef SUNOS4_SHARED_LIBRARIES
66 #undef OBJECT_FORMAT_COFF
67 #undef OBJECT_FORMAT_ROSE
69 #undef REAL_LD_FILE_NAME
70 #undef REAL_NM_FILE_NAME
71 #undef REAL_STRIP_FILE_NAME
74 /* If we cannot use a special method, use the ordinary one:
75 run nm to find what symbols are present.
76 In a cross-compiler, this means you need a cross nm,
77 but that is not quite as unpleasant as special headers. */
79 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
80 #define OBJECT_FORMAT_NONE
83 #ifdef OBJECT_FORMAT_COFF
92 /* Many versions of ldfcn.h define these. */
100 /* Some systems have an ISCOFF macro, but others do not. In some cases
101 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
102 that either do not have an ISCOFF macro in /usr/include or for those
103 where it is wrong. */
106 #define MY_ISCOFF(X) ISCOFF (X)
109 #endif /* OBJECT_FORMAT_COFF */
111 #ifdef OBJECT_FORMAT_ROSE
118 #include <sys/mman.h>
122 #include <mach_o_format.h>
123 #include <mach_o_header.h>
124 #include <mach_o_vals.h>
125 #include <mach_o_types.h>
127 #endif /* OBJECT_FORMAT_ROSE */
129 #ifdef OBJECT_FORMAT_NONE
131 /* Default flags to pass to nm. */
133 #define NM_FLAGS "-n"
136 #endif /* OBJECT_FORMAT_NONE */
138 /* Some systems use __main in a way incompatible with its use in gcc, in these
139 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
140 give the same symbol without quotes for an alternative entry point. You
141 must define both, or neither. */
143 #define NAME__MAIN "__main"
144 #define SYMBOL__MAIN __main
147 /* This must match tree.h. */
148 #define DEFAULT_INIT_PRIORITY 65535
150 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
151 #define SCAN_LIBRARIES
155 int do_collecting
= 1;
157 int do_collecting
= 0;
160 /* Linked lists of constructor and destructor names. */
176 /* Enumeration giving which pass this is for scanning the program file. */
179 PASS_FIRST
, /* without constructors */
180 PASS_OBJ
, /* individual objects */
181 PASS_LIB
, /* looking for shared libraries */
182 PASS_SECOND
/* with constructors linked in */
185 extern char *version_string
;
187 int vflag
; /* true if -v */
188 static int rflag
; /* true if -r */
189 static int strip_flag
; /* true if -s */
190 #ifdef COLLECT_EXPORT_LIST
191 static int export_flag
; /* true if -bE */
192 static int aix64_flag
; /* true if -b64 */
195 int debug
; /* true if -debug */
197 static int shared_obj
; /* true if -shared */
199 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
200 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
201 #ifdef COLLECT_EXPORT_LIST
202 static const char *export_file
; /* <xxx>.x for AIX export list. */
203 static const char *import_file
; /* <xxx>.p for AIX import list. */
205 const char *ldout
; /* File for ld errors. */
206 static const char *output_file
; /* Output file for ld. */
207 static const char *nm_file_name
; /* pathname of nm */
209 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
211 static const char *strip_file_name
; /* pathname of strip */
212 const char *c_file_name
; /* pathname of gcc */
213 static char *initname
, *fininame
; /* names of init and fini funcs */
215 static struct head constructors
; /* list of constructors found */
216 static struct head destructors
; /* list of destructors found */
217 #ifdef COLLECT_EXPORT_LIST
218 static struct head exports
; /* list of exported symbols */
219 static struct head imports
; /* list of imported symbols */
220 static struct head undefined
; /* list of undefined symbols */
222 static struct head frame_tables
; /* list of frame unwind info tables */
224 struct obstack temporary_obstack
;
225 struct obstack permanent_obstack
;
226 char * temporary_firstobj
;
228 /* Holds the return value of pexecute. */
231 /* Defined in the automatically-generated underscore.c. */
232 extern int prepends_underscore
;
234 #ifndef GET_ENV_PATH_LIST
235 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
238 /* Structure to hold all the directories in which to search for files to
243 const char *prefix
; /* String to prepend to the path. */
244 struct prefix_list
*next
; /* Next in linked list. */
249 struct prefix_list
*plist
; /* List of prefixes to try */
250 int max_len
; /* Max length of a prefix in PLIST */
251 const char *name
; /* Name of this list (used in config stuff) */
254 #ifdef COLLECT_EXPORT_LIST
255 /* Lists to keep libraries to be scanned for global constructors/destructors. */
256 static struct head libs
; /* list of libraries */
257 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
258 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
259 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
260 &libpath_lib_dirs
, NULL
};
261 static const char *libexts
[3] = {"a", "so", NULL
}; /* possible library extentions */
264 static const char *my_strsignal
PROTO((int));
265 static void handler
PROTO((int));
266 static int is_ctor_dtor
PROTO((const char *));
267 static char *find_a_file
PROTO((struct path_prefix
*, const char *));
268 static void add_prefix
PROTO((struct path_prefix
*, const char *));
269 static void prefix_from_env
PROTO((const char *, struct path_prefix
*));
270 static void prefix_from_string
PROTO((const char *, struct path_prefix
*));
271 static void do_wait
PROTO((const char *));
272 static void fork_execute
PROTO((const char *, char **));
273 static void maybe_unlink
PROTO((const char *));
274 static void add_to_list
PROTO((struct head
*, const char *));
275 static int extract_init_priority
PROTO((const char *));
276 static void sort_ids
PROTO((struct head
*));
277 static void write_list
PROTO((FILE *, const char *, struct id
*));
278 #ifdef COLLECT_EXPORT_LIST
279 static void dump_list
PROTO((FILE *, const char *, struct id
*));
282 static void dump_prefix_list
PROTO((FILE *, const char *, struct prefix_list
*));
284 static void write_list_with_asm
PROTO((FILE *, const char *, struct id
*));
285 static void write_c_file
PROTO((FILE *, const char *));
286 static void write_c_file_stat
PROTO((FILE *, const char *));
287 #ifndef LD_INIT_SWITCH
288 static void write_c_file_glob
PROTO((FILE *, const char *));
290 static void scan_prog_file
PROTO((const char *, enum pass
));
291 #ifdef SCAN_LIBRARIES
292 static void scan_libraries
PROTO((const char *));
294 #ifdef COLLECT_EXPORT_LIST
295 static int is_in_list
PROTO((const char *, struct id
*));
296 static void write_aix_file
PROTO((FILE *, struct id
*));
297 static char *resolve_lib_name
PROTO((const char *));
298 static int use_import_list
PROTO((const char *));
299 static int ignore_library
PROTO((const char *));
301 static char *extract_string
PROTO((const char **));
316 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
319 close (fdtmp
[--fdx
]);
329 #ifdef HAVE_STRSIGNAL
330 return strsignal (s
);
332 if (s
>= 0 && s
< NSIG
)
334 # ifdef NO_SYS_SIGLIST
335 static char buffer
[30];
337 sprintf (buffer
, "Unknown signal %d", s
);
340 return sys_siglist
[s
];
345 #endif /* HAVE_STRSIGNAL */
348 /* Delete tempfiles and exit function. */
351 collect_exit (status
)
354 if (c_file
!= 0 && c_file
[0])
355 maybe_unlink (c_file
);
357 if (o_file
!= 0 && o_file
[0])
358 maybe_unlink (o_file
);
360 #ifdef COLLECT_EXPORT_LIST
361 if (export_file
!= 0 && export_file
[0])
362 maybe_unlink (export_file
);
364 if (import_file
!= 0 && import_file
[0])
365 maybe_unlink (import_file
);
368 if (ldout
!= 0 && ldout
[0])
371 maybe_unlink (ldout
);
374 if (status
!= 0 && output_file
!= 0 && output_file
[0])
375 maybe_unlink (output_file
);
381 /* Notify user of a non-error. */
383 notice
VPROTO((const char *msgid
, ...))
385 #ifndef ANSI_PROTOTYPES
390 VA_START (ap
, msgid
);
392 #ifndef ANSI_PROTOTYPES
393 msgid
= va_arg (ap
, const char *);
396 vfprintf (stderr
, _(msgid
), ap
);
400 /* Die when sys call fails. */
403 fatal_perror
VPROTO((const char * msgid
, ...))
405 #ifndef ANSI_PROTOTYPES
411 VA_START (ap
, msgid
);
413 #ifndef ANSI_PROTOTYPES
414 msgid
= va_arg (ap
, const char *);
417 fprintf (stderr
, "collect2: ");
418 vfprintf (stderr
, _(msgid
), ap
);
419 fprintf (stderr
, ": %s\n", xstrerror (e
));
422 collect_exit (FATAL_EXIT_CODE
);
428 fatal
VPROTO((const char * msgid
, ...))
430 #ifndef ANSI_PROTOTYPES
435 VA_START (ap
, msgid
);
437 #ifndef ANSI_PROTOTYPES
438 msgid
= va_arg (ap
, const char *);
441 fprintf (stderr
, "collect2: ");
442 vfprintf (stderr
, _(msgid
), ap
);
443 fprintf (stderr
, "\n");
446 collect_exit (FATAL_EXIT_CODE
);
449 /* Write error message. */
452 error
VPROTO((const char * msgid
, ...))
454 #ifndef ANSI_PROTOTYPES
459 VA_START (ap
, msgid
);
461 #ifndef ANSI_PROTOTYPES
462 msgid
= va_arg (ap
, const char *);
465 fprintf (stderr
, "collect2: ");
466 vfprintf (stderr
, _(msgid
), ap
);
467 fprintf (stderr
, "\n");
471 /* In case obstack is linked in, and abort is defined to fancy_abort,
472 provide a default entry. */
477 fatal ("internal error");
484 if (c_file
!= 0 && c_file
[0])
485 maybe_unlink (c_file
);
487 if (o_file
!= 0 && o_file
[0])
488 maybe_unlink (o_file
);
490 if (ldout
!= 0 && ldout
[0])
491 maybe_unlink (ldout
);
493 #ifdef COLLECT_EXPORT_LIST
494 if (export_file
!= 0 && export_file
[0])
495 maybe_unlink (export_file
);
497 if (import_file
!= 0 && import_file
[0])
498 maybe_unlink (import_file
);
501 signal (signo
, SIG_DFL
);
502 kill (getpid (), signo
);
510 return access (name
, R_OK
) == 0;
513 /* Parse a reasonable subset of shell quoting syntax. */
530 obstack_1grow (&temporary_obstack
, c
);
531 else if (! inside
&& c
== ' ')
533 else if (! inside
&& c
== '\\')
538 obstack_1grow (&temporary_obstack
, c
);
541 obstack_1grow (&temporary_obstack
, '\0');
543 return obstack_finish (&temporary_obstack
);
550 FILE *stream
= fopen (name
, "r");
551 int no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
558 while (c
= getc (stream
),
559 c
!= EOF
&& (ISALNUM (c
) || c
== '_' || c
== '$' || c
== '.'))
560 obstack_1grow (&temporary_obstack
, c
);
561 if (obstack_object_size (&temporary_obstack
) > 0)
563 const char *word
, *p
;
565 obstack_1grow (&temporary_obstack
, '\0');
566 word
= obstack_finish (&temporary_obstack
);
569 ++word
, putc ('.', stderr
);
571 if (*p
== '_' && prepends_underscore
)
577 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
);
582 fputs (result
, stderr
);
584 diff
= strlen (word
) - strlen (result
);
586 --diff
, putc (' ', stderr
);
587 while (diff
< 0 && c
== ' ')
588 ++diff
, c
= getc (stream
);
593 fputs (word
, stderr
);
596 obstack_free (&temporary_obstack
, temporary_firstobj
);
605 /* Decide whether the given symbol is:
606 a constructor (1), a destructor (2), or neither (0). */
612 struct names
{ const char *name
; int len
; int ret
; int two_underscores
; };
614 register struct names
*p
;
616 register const char *orig_s
= s
;
618 static struct names special
[] = {
619 #ifdef NO_DOLLAR_IN_LABEL
620 #ifdef NO_DOT_IN_LABEL
621 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
622 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
623 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
625 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
626 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
627 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
630 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
631 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
632 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
634 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
635 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
636 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
637 cfront has its own linker procedure to collect them;
638 if collect2 gets them too, they get collected twice
639 when the cfront procedure is run and the compiler used
640 for linking happens to be GCC. */
641 { "sti__", sizeof ("sti__")-1, 1, 1 },
642 { "std__", sizeof ("std__")-1, 2, 1 },
643 #endif /* CFRONT_LOSSAGE */
647 while ((ch
= *s
) == '_')
653 for (p
= &special
[0]; p
->len
> 0; p
++)
656 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
657 && strncmp(s
, p
->name
, p
->len
) == 0)
665 /* By default, colon separates directories in a path. */
666 #ifndef PATH_SEPARATOR
667 #define PATH_SEPARATOR ':'
670 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
671 and one from the PATH variable. */
673 static struct path_prefix cpath
, path
;
676 /* This is the name of the target machine. We use it to form the name
677 of the files to execute. */
679 static const char *const target_machine
= TARGET_MACHINE
;
682 /* Search for NAME using prefix list PPREFIX. We only look for executable
685 Return 0 if not found, otherwise return its name, allocated with malloc. */
688 find_a_file (pprefix
, name
)
689 struct path_prefix
*pprefix
;
693 struct prefix_list
*pl
;
694 int len
= pprefix
->max_len
+ strlen (name
) + 1;
697 fprintf (stderr
, "Looking for '%s'\n", name
);
699 #ifdef EXECUTABLE_SUFFIX
700 len
+= strlen (EXECUTABLE_SUFFIX
);
703 temp
= xmalloc (len
);
705 /* Determine the filename to execute (special case for absolute paths). */
708 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
709 || (*name
&& name
[1] == ':')
713 if (access (name
, X_OK
) == 0)
718 fprintf (stderr
, " - found: absolute path\n");
723 #ifdef EXECUTABLE_SUFFIX
724 /* Some systems have a suffix for executable files.
725 So try appending that. */
727 strcat (temp
, EXECUTABLE_SUFFIX
);
729 if (access (temp
, X_OK
) == 0)
734 fprintf (stderr
, " - failed to locate using absolute path\n");
737 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
741 strcpy (temp
, pl
->prefix
);
744 if (stat (temp
, &st
) >= 0
745 && ! S_ISDIR (st
.st_mode
)
746 && access (temp
, X_OK
) == 0)
749 #ifdef EXECUTABLE_SUFFIX
750 /* Some systems have a suffix for executable files.
751 So try appending that. */
752 strcat (temp
, EXECUTABLE_SUFFIX
);
754 if (stat (temp
, &st
) >= 0
755 && ! S_ISDIR (st
.st_mode
)
756 && access (temp
, X_OK
) == 0)
761 if (debug
&& pprefix
->plist
== NULL
)
762 fprintf (stderr
, " - failed: no entries in prefix list\n");
768 /* Add an entry for PREFIX to prefix list PPREFIX. */
771 add_prefix (pprefix
, prefix
)
772 struct path_prefix
*pprefix
;
775 struct prefix_list
*pl
, **prev
;
780 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
785 prev
= &pprefix
->plist
;
787 /* Keep track of the longest prefix */
789 len
= strlen (prefix
);
790 if (len
> pprefix
->max_len
)
791 pprefix
->max_len
= len
;
793 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
794 pl
->prefix
= xstrdup (prefix
);
799 pl
->next
= (struct prefix_list
*) 0;
803 /* Take the value of the environment variable ENV, break it into a path, and
804 add of the entries to PPREFIX. */
807 prefix_from_env (env
, pprefix
)
809 struct path_prefix
*pprefix
;
812 GET_ENV_PATH_LIST (p
, env
);
815 prefix_from_string (p
, pprefix
);
819 prefix_from_string (p
, pprefix
)
821 struct path_prefix
*pprefix
;
823 const char *startp
, *endp
;
824 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
827 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
832 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
834 strncpy (nstore
, startp
, endp
-startp
);
837 strcpy (nstore
, "./");
839 else if (endp
[-1] != '/')
841 nstore
[endp
-startp
] = '/';
842 nstore
[endp
-startp
+1] = 0;
845 nstore
[endp
-startp
] = 0;
848 fprintf (stderr
, " - add prefix: %s\n", nstore
);
850 add_prefix (pprefix
, nstore
);
853 endp
= startp
= endp
+ 1;
862 int main
PROTO ((int, char *[]));
868 const char *ld_suffix
= "ld";
869 const char *full_ld_suffix
= ld_suffix
;
870 const char *real_ld_suffix
= "real-ld";
871 const char *collect_ld_suffix
= "collect-ld";
872 const char *nm_suffix
= "nm";
873 const char *full_nm_suffix
= nm_suffix
;
874 const char *gnm_suffix
= "gnm";
875 const char *full_gnm_suffix
= gnm_suffix
;
877 const char *ldd_suffix
= LDD_SUFFIX
;
878 const char *full_ldd_suffix
= ldd_suffix
;
880 const char *strip_suffix
= "strip";
881 const char *full_strip_suffix
= strip_suffix
;
882 const char *gstrip_suffix
= "gstrip";
883 const char *full_gstrip_suffix
= gstrip_suffix
;
886 #ifdef COLLECT_EXPORT_LIST
890 const char *ld_file_name
;
901 int num_c_args
= argc
+9;
903 #if defined (COLLECT2_HOST_INITIALIZATION)
904 /* Perform system dependant initialization, if neccessary. */
905 COLLECT2_HOST_INITIALIZATION
;
908 #ifdef HAVE_LC_MESSAGES
909 setlocale (LC_MESSAGES
, "");
911 (void) bindtextdomain (PACKAGE
, localedir
);
912 (void) textdomain (PACKAGE
);
914 /* Do not invoke xcalloc before this point, since locale needs to be
915 set first, in case a diagnostic is issued. */
917 ld1
= (const char **)(ld1_argv
= (char **) xcalloc(sizeof (char *), argc
+3));
918 ld2
= (const char **)(ld2_argv
= (char **) xcalloc(sizeof (char *), argc
+6));
919 object
= (const char **)(object_lst
= (char **) xcalloc(sizeof (char *), argc
));
925 /* Parse command line early for instances of -debug. This allows
926 the debug flag to be set before functions like find_a_file()
931 for (i
= 1; argv
[i
] != NULL
; i
++)
932 if (! strcmp (argv
[i
], "-debug"))
937 #ifndef DEFAULT_A_OUT_NAME
938 output_file
= "a.out";
940 output_file
= DEFAULT_A_OUT_NAME
;
943 obstack_begin (&temporary_obstack
, 0);
944 obstack_begin (&permanent_obstack
, 0);
945 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
947 current_demangling_style
= gnu_demangling
;
948 p
= getenv ("COLLECT_GCC_OPTIONS");
951 const char *q
= extract_string (&p
);
952 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
955 obstack_free (&temporary_obstack
, temporary_firstobj
);
958 c_ptr
= (const char **)
959 (c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
));
962 fatal ("no arguments");
965 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
966 signal (SIGQUIT
, handler
);
968 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
969 signal (SIGINT
, handler
);
971 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
972 signal (SIGALRM
, handler
);
975 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
976 signal (SIGHUP
, handler
);
978 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
979 signal (SIGSEGV
, handler
);
981 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
982 signal (SIGBUS
, handler
);
985 /* Extract COMPILER_PATH and PATH into our prefix list. */
986 prefix_from_env ("COMPILER_PATH", &cpath
);
987 prefix_from_env ("PATH", &path
);
990 /* If we look for a program in the compiler directories, we just use
991 the short name, since these directories are already system-specific.
992 But it we look for a program in the system directories, we need to
993 qualify the program name with the target machine. */
995 full_ld_suffix
= concat(target_machine
, "-", ld_suffix
, NULL
);
998 full_gld_suffix
= concat (target_machine
, "-", gld_suffix
, NULL
);
1001 full_nm_suffix
= concat (target_machine
, "-", nm_suffix
, NULL
);
1003 full_gnm_suffix
= concat (target_machine
, "-", gnm_suffix
, NULL
);
1006 full_ldd_suffix
= concat (target_machine
, "-", ldd_suffix
, NULL
);
1009 full_strip_suffix
= concat (target_machine
, "-", strip_suffix
, NULL
);
1011 full_gstrip_suffix
= concat (target_machine
, "-", gstrip_suffix
, NULL
);
1012 #endif /* CROSS_COMPILE */
1014 /* Try to discover a valid linker/nm/strip to use. */
1016 /* Maybe we know the right file to use (if not cross). */
1018 #ifdef DEFAULT_LINKER
1019 if (access (DEFAULT_LINKER
, X_OK
) == 0)
1020 ld_file_name
= DEFAULT_LINKER
;
1021 if (ld_file_name
== 0)
1023 #ifdef REAL_LD_FILE_NAME
1024 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
1025 if (ld_file_name
== 0)
1027 /* Search the (target-specific) compiler dirs for ld'. */
1028 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
1029 /* Likewise for `collect-ld'. */
1030 if (ld_file_name
== 0)
1031 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
1032 /* Search the compiler directories for `ld'. We have protection against
1033 recursive calls in find_a_file. */
1034 if (ld_file_name
== 0)
1035 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
1036 /* Search the ordinary system bin directories
1037 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1038 if (ld_file_name
== 0)
1039 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
1041 #ifdef REAL_NM_FILE_NAME
1042 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
1043 if (nm_file_name
== 0)
1045 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
1046 if (nm_file_name
== 0)
1047 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
1048 if (nm_file_name
== 0)
1049 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
1050 if (nm_file_name
== 0)
1051 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
1054 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
1055 if (ldd_file_name
== 0)
1056 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
1059 #ifdef REAL_STRIP_FILE_NAME
1060 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1061 if (strip_file_name
== 0)
1063 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1064 if (strip_file_name
== 0)
1065 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1066 if (strip_file_name
== 0)
1067 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1068 if (strip_file_name
== 0)
1069 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1071 /* Determine the full path name of the C compiler to use. */
1072 c_file_name
= getenv ("COLLECT_GCC");
1073 if (c_file_name
== 0)
1075 #ifdef CROSS_COMPILE
1076 c_file_name
= concat (target_machine
, "-gcc", NULL
);
1078 c_file_name
= "gcc";
1082 p
= find_a_file (&cpath
, c_file_name
);
1084 /* Here it should be safe to use the system search path since we should have
1085 already qualified the name of the compiler when it is needed. */
1087 p
= find_a_file (&path
, c_file_name
);
1092 *ld1
++ = *ld2
++ = ld_file_name
;
1094 /* Make temp file names. */
1095 c_file
= make_temp_file (".c");
1096 o_file
= make_temp_file (".o");
1097 #ifdef COLLECT_EXPORT_LIST
1098 export_file
= make_temp_file (".x");
1099 import_file
= make_temp_file (".p");
1101 ldout
= make_temp_file (".ld");
1102 *c_ptr
++ = c_file_name
;
1109 #ifdef COLLECT_EXPORT_LIST
1110 /* Generate a list of directories from LIBPATH. */
1111 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1112 /* Add to this list also two standard directories where
1113 AIX loader always searches for libraries. */
1114 add_prefix (&libpath_lib_dirs
, "/lib");
1115 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1118 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1120 AIX support needs to know if -shared has been specified before
1121 parsing commandline arguments. */
1123 p
= getenv ("COLLECT_GCC_OPTIONS");
1126 const char *q
= extract_string (&p
);
1127 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1128 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1129 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1130 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1131 if (strncmp (q
, "-shared", sizeof ("-shared") - 1) == 0)
1134 obstack_free (&temporary_obstack
, temporary_firstobj
);
1135 *c_ptr
++ = "-fno-exceptions";
1137 /* !!! When GCC calls collect2,
1138 it does not know whether it is calling collect2 or ld.
1139 So collect2 cannot meaningfully understand any options
1140 except those ld understands.
1141 If you propose to make GCC pass some other option,
1142 just imagine what will happen if ld is really ld!!! */
1144 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1145 /* After the first file, put in the c++ rt0. */
1148 while ((arg
= *++argv
) != (char *) 0)
1150 *ld1
++ = *ld2
++ = arg
;
1156 #ifdef COLLECT_EXPORT_LIST
1157 /* We want to disable automatic exports on AIX when user
1158 explicitly puts an export list in command line */
1160 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1162 else if (arg
[2] == '6' && arg
[3] == '4')
1168 if (!strcmp (arg
, "-debug"))
1170 /* Already parsed. */
1179 /* place o_file BEFORE this argument! */
1185 #ifdef COLLECT_EXPORT_LIST
1187 /* Resolving full library name. */
1188 const char *s
= resolve_lib_name (arg
+2);
1190 /* If we will use an import list for this library,
1191 we should exclude it from ld args. */
1192 if (use_import_list (s
))
1198 /* Saving a full library name. */
1199 add_to_list (&libs
, s
);
1204 #ifdef COLLECT_EXPORT_LIST
1205 /* Saving directories where to search for libraries. */
1207 add_prefix (&cmdline_lib_dirs
, arg
+2);
1213 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1215 output_file
= &arg
[2];
1224 if (arg
[2] == '\0' && do_collecting
)
1226 /* We must strip after the nm run, otherwise C++ linking
1227 will not work. Thus we strip in the second ld run, or
1228 else with strip if there is no second ld run. */
1240 else if ((p
= rindex (arg
, '.')) != (char *) 0
1241 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1242 || strcmp (p
, ".so") == 0))
1251 /* place o_file BEFORE this argument! */
1259 #ifdef COLLECT_EXPORT_LIST
1260 /* libraries can be specified directly, i.e. without -l flag. */
1263 /* If we will use an import list for this library,
1264 we should exclude it from ld args. */
1265 if (use_import_list (arg
))
1271 /* Saving a full library name. */
1272 add_to_list (&libs
, arg
);
1278 #ifdef COLLECT_EXPORT_LIST
1279 /* This is added only for debugging purposes. */
1282 fprintf (stderr
, "List of libraries:\n");
1283 dump_list (stderr
, "\t", libs
.first
);
1286 /* The AIX linker will discard static constructors in object files if
1287 nothing else in the file is referenced, so look at them first. */
1289 char **export_object_lst
= object_lst
;
1291 while (export_object_lst
< object
)
1292 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1295 struct id
*list
= libs
.first
;
1297 for (; list
; list
= list
->next
)
1298 scan_prog_file (list
->name
, PASS_FIRST
);
1303 char *buf
= xmalloc (strlen (export_file
) + 5);
1305 sprintf (buf
, "-bE:%s", export_file
);
1309 exportf
= fopen (export_file
, "w");
1310 if (exportf
== (FILE *) 0)
1311 fatal_perror ("fopen %s", export_file
);
1312 write_aix_file (exportf
, exports
.first
);
1313 if (fclose (exportf
))
1314 fatal_perror ("fclose %s", export_file
);
1319 char *buf
= xmalloc (strlen (import_file
) + 5);
1321 sprintf (buf
, "-bI:%s", import_file
);
1325 importf
= fopen (import_file
, "w");
1326 if (importf
== (FILE *) 0)
1327 fatal_perror ("%s", import_file
);
1328 fputs ("#! .\n", importf
);
1329 write_aix_file (importf
, imports
.first
);
1330 if (fclose (importf
))
1331 fatal_perror ("fclose %s", import_file
);
1336 *c_ptr
= *ld1
= *object
= (char *) 0;
1340 notice ("collect2 version %s", version_string
);
1341 #ifdef TARGET_VERSION
1344 fprintf (stderr
, "\n");
1350 fprintf (stderr
, "ld_file_name = %s\n",
1351 (ld_file_name
? ld_file_name
: "not found"));
1352 fprintf (stderr
, "c_file_name = %s\n",
1353 (c_file_name
? c_file_name
: "not found"));
1354 fprintf (stderr
, "nm_file_name = %s\n",
1355 (nm_file_name
? nm_file_name
: "not found"));
1357 fprintf (stderr
, "ldd_file_name = %s\n",
1358 (ldd_file_name
? ldd_file_name
: "not found"));
1360 fprintf (stderr
, "strip_file_name = %s\n",
1361 (strip_file_name
? strip_file_name
: "not found"));
1362 fprintf (stderr
, "c_file = %s\n",
1363 (c_file
? c_file
: "not found"));
1364 fprintf (stderr
, "o_file = %s\n",
1365 (o_file
? o_file
: "not found"));
1367 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1369 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1371 ptr
= getenv ("COLLECT_GCC");
1373 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1375 ptr
= getenv ("COMPILER_PATH");
1377 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1379 ptr
= getenv ("LIBRARY_PATH");
1381 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
1383 fprintf (stderr
, "\n");
1386 /* Load the program, searching all libraries and attempting to provide
1387 undefined symbols from repository information. */
1389 /* On AIX we do this later. */
1390 #ifndef COLLECT_EXPORT_LIST
1391 do_tlink (ld1_argv
, object_lst
);
1394 /* If -r or they will be run via some other method, do not build the
1395 constructor or destructor list, just return now. */
1397 #ifndef COLLECT_EXPORT_LIST
1402 #ifdef COLLECT_EXPORT_LIST
1403 /* But make sure we delete the export file we may have created. */
1404 if (export_file
!= 0 && export_file
[0])
1405 maybe_unlink (export_file
);
1406 if (import_file
!= 0 && import_file
[0])
1407 maybe_unlink (import_file
);
1409 maybe_unlink (c_file
);
1410 maybe_unlink (o_file
);
1414 /* Examine the namelist with nm and search it for static constructors
1415 and destructors to call.
1416 Write the constructor and destructor tables to a .s file and reload. */
1418 /* On AIX we already scanned for global constructors/destructors. */
1419 #ifndef COLLECT_EXPORT_LIST
1420 scan_prog_file (output_file
, PASS_FIRST
);
1423 #ifdef SCAN_LIBRARIES
1424 scan_libraries (output_file
);
1429 notice ("%d constructor(s) found\n", constructors
.number
);
1430 notice ("%d destructor(s) found\n", destructors
.number
);
1431 notice ("%d frame table(s) found\n", frame_tables
.number
);
1434 if (constructors
.number
== 0 && destructors
.number
== 0
1435 && frame_tables
.number
== 0
1436 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1437 /* If we will be running these functions ourselves, we want to emit
1438 stubs into the shared library so that we do not have to relink
1439 dependent programs when we add static objects. */
1444 #ifdef COLLECT_EXPORT_LIST
1445 /* Do tlink without additional code generation */
1446 do_tlink (ld1_argv
, object_lst
);
1448 /* Strip now if it was requested on the command line. */
1451 char **real_strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1452 const char ** strip_argv
= (const char **) real_strip_argv
;
1454 strip_argv
[0] = strip_file_name
;
1455 strip_argv
[1] = output_file
;
1456 strip_argv
[2] = (char *) 0;
1457 fork_execute ("strip", real_strip_argv
);
1460 #ifdef COLLECT_EXPORT_LIST
1461 maybe_unlink (export_file
);
1462 maybe_unlink (import_file
);
1464 maybe_unlink (c_file
);
1465 maybe_unlink (o_file
);
1469 /* Sort ctor and dtor lists by priority. */
1470 sort_ids (&constructors
);
1471 sort_ids (&destructors
);
1473 maybe_unlink(output_file
);
1474 outf
= fopen (c_file
, "w");
1475 if (outf
== (FILE *) 0)
1476 fatal_perror ("fopen %s", c_file
);
1478 write_c_file (outf
, c_file
);
1481 fatal_perror ("fclose %s", c_file
);
1483 /* Tell the linker that we have initializer and finalizer functions. */
1484 #ifdef LD_INIT_SWITCH
1485 *ld2
++ = LD_INIT_SWITCH
;
1487 *ld2
++ = LD_FINI_SWITCH
;
1491 #ifdef COLLECT_EXPORT_LIST
1494 /* If we did not add export flag to link arguments before, add it to
1495 second link phase now. No new exports should have been added. */
1496 if (! exports
.first
)
1498 char *buf
= xmalloc (strlen (export_file
) + 5);
1500 sprintf (buf
, "-bE:%s", export_file
);
1504 add_to_list (&exports
, initname
);
1505 add_to_list (&exports
, fininame
);
1506 add_to_list (&exports
, "_GLOBAL__DI");
1507 add_to_list (&exports
, "_GLOBAL__DD");
1508 exportf
= fopen (export_file
, "w");
1509 if (exportf
== (FILE *) 0)
1510 fatal_perror ("fopen %s", export_file
);
1511 write_aix_file (exportf
, exports
.first
);
1512 if (fclose (exportf
))
1513 fatal_perror ("fclose %s", export_file
);
1517 /* End of arguments to second link phase. */
1522 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1523 output_file
, c_file
);
1524 write_c_file (stderr
, "stderr");
1525 fprintf (stderr
, "========== end of c_file\n\n");
1526 #ifdef COLLECT_EXPORT_LIST
1527 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1528 write_aix_file (stderr
, exports
.first
);
1529 fprintf (stderr
, "========== end of export_file\n\n");
1533 /* Assemble the constructor and destructor tables.
1534 Link the tables in with the rest of the program. */
1536 fork_execute ("gcc", c_argv
);
1537 #ifdef COLLECT_EXPORT_LIST
1538 /* On AIX we must call tlink because of possible templates resolution */
1539 do_tlink (ld2_argv
, object_lst
);
1541 /* Otherwise, simply call ld because tlink is already done */
1542 fork_execute ("ld", ld2_argv
);
1544 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1545 constructors/destructors in shared libraries. */
1546 scan_prog_file (output_file
, PASS_SECOND
);
1549 maybe_unlink (c_file
);
1550 maybe_unlink (o_file
);
1552 #ifdef COLLECT_EXPORT_LIST
1553 maybe_unlink (export_file
);
1554 maybe_unlink (import_file
);
1561 /* Wait for a process to finish, and exit if a non-zero status is found. */
1569 pwait (pexecute_pid
, &status
, 0);
1572 if (WIFSIGNALED (status
))
1574 int sig
= WTERMSIG (status
);
1575 error ((status
& 0200
1576 ? "%s terminated with signal %d [%s]"
1577 : "%s terminated with signal %d [%s], core dumped"),
1581 collect_exit (FATAL_EXIT_CODE
);
1584 if (WIFEXITED (status
))
1585 return WEXITSTATUS (status
);
1594 int ret
= collect_wait (prog
);
1597 error ("%s returned %d exit status", prog
, ret
);
1603 /* Execute a program, and wait for the reply. */
1606 collect_execute (prog
, argv
, redir
)
1613 int redir_handle
= -1;
1614 int stdout_save
= -1;
1615 int stderr_save
= -1;
1623 fprintf (stderr
, "%s", argv
[0]);
1625 notice ("[cannot find %s]", prog
);
1627 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1628 fprintf (stderr
, " %s", str
);
1630 fprintf (stderr
, "\n");
1636 /* If we cannot find a program we need, complain error. Do this here
1637 since we might not end up needing something that we could not find. */
1640 fatal ("cannot find `%s'", prog
);
1644 /* Open response file. */
1645 redir_handle
= open (redir
, O_WRONLY
| O_TRUNC
| O_CREAT
);
1647 /* Duplicate the stdout and stderr file handles
1648 so they can be restored later. */
1649 stdout_save
= dup (STDOUT_FILENO
);
1650 if (stdout_save
== -1)
1651 fatal_perror ("redirecting stdout: %s", redir
);
1652 stderr_save
= dup (STDERR_FILENO
);
1653 if (stderr_save
== -1)
1654 fatal_perror ("redirecting stdout: %s", redir
);
1656 /* Redirect stdout & stderr to our response file. */
1657 dup2 (redir_handle
, STDOUT_FILENO
);
1658 dup2 (redir_handle
, STDERR_FILENO
);
1661 pexecute_pid
= pexecute (argv
[0], argv
, argv
[0], NULL
,
1662 &errmsg_fmt
, &errmsg_arg
,
1663 (PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
));
1667 /* Restore stdout and stderr to their previous settings. */
1668 dup2 (stdout_save
, STDOUT_FILENO
);
1669 dup2 (stderr_save
, STDERR_FILENO
);
1671 /* Close reponse file. */
1672 close (redir_handle
);
1675 if (pexecute_pid
== -1)
1676 fatal_perror (errmsg_fmt
, errmsg_arg
);
1680 fork_execute (prog
, argv
)
1684 collect_execute (prog
, argv
, NULL
);
1688 /* Unlink a file unless we are debugging. */
1697 notice ("[Leaving %s]\n", file
);
1701 static long sequence_number
= 0;
1703 /* Add a name to a linked list. */
1706 add_to_list (head_ptr
, name
)
1707 struct head
*head_ptr
;
1711 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1713 strcpy (newid
->name
, name
);
1715 if (head_ptr
->first
)
1716 head_ptr
->last
->next
= newid
;
1718 head_ptr
->first
= newid
;
1720 /* Check for duplicate symbols. */
1721 for (p
= head_ptr
->first
;
1722 strcmp (name
, p
->name
) != 0;
1727 head_ptr
->last
->next
= 0;
1732 newid
->sequence
= ++sequence_number
;
1733 head_ptr
->last
= newid
;
1737 /* Grab the init priority number from an init function name that
1738 looks like "_GLOBAL_.I.12345.foo". */
1741 extract_init_priority (name
)
1746 while (name
[pos
] == '_')
1748 pos
+= 10; /* strlen ("GLOBAL__X_") */
1750 /* Extract init_p number from ctor/dtor name. */
1751 pri
= atoi (name
+ pos
);
1752 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1755 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1756 ctors will be run from right to left, dtors from left to right. */
1760 struct head
*head_ptr
;
1762 /* id holds the current element to insert. id_next holds the next
1763 element to insert. id_ptr iterates through the already sorted elements
1764 looking for the place to insert id. */
1765 struct id
*id
, *id_next
, **id_ptr
;
1767 id
= head_ptr
->first
;
1769 /* We don't have any sorted elements yet. */
1770 head_ptr
->first
= NULL
;
1772 for (; id
; id
= id_next
)
1775 id
->sequence
= extract_init_priority (id
->name
);
1777 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1779 /* If the sequence numbers are the same, we put the id from the
1780 file later on the command line later in the list. */
1781 || id
->sequence
> (*id_ptr
)->sequence
1782 /* Hack: do lexical compare, too.
1783 || (id->sequence == (*id_ptr)->sequence
1784 && strcmp (id->name, (*id_ptr)->name) > 0) */
1793 /* Now set the sequence numbers properly so write_c_file works. */
1794 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1795 id
->sequence
= ++sequence_number
;
1798 /* Write: `prefix', the names on list LIST, `suffix'. */
1801 write_list (stream
, prefix
, list
)
1808 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1813 #ifdef COLLECT_EXPORT_LIST
1814 /* This function is really used only on AIX, but may be useful. */
1816 is_in_list (prefix
, list
)
1822 if (!strcmp (prefix
, list
->name
)) return 1;
1829 /* Added for debugging purpose. */
1830 #ifdef COLLECT_EXPORT_LIST
1832 dump_list (stream
, prefix
, list
)
1839 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1847 dump_prefix_list (stream
, prefix
, list
)
1850 struct prefix_list
*list
;
1854 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1861 write_list_with_asm (stream
, prefix
, list
)
1868 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1869 prefix
, list
->sequence
, list
->name
);
1874 /* Write out the constructor and destructor tables statically (for a shared
1875 object), along with the functions to execute them. */
1878 write_c_file_stat (stream
, name
)
1880 const char *name ATTRIBUTE_UNUSED
;
1884 int frames
= (frame_tables
.number
> 0);
1886 /* Figure out name of output_file, stripping off .so version. */
1887 p
= rindex (output_file
, '/');
1903 if (strncmp (q
, ".so", 3) == 0)
1912 /* q points to null at end of the string (or . of the .so version) */
1913 prefix
= xmalloc (q
- p
+ 1);
1914 strncpy (prefix
, p
, q
- p
);
1916 for (r
= prefix
; *r
; r
++)
1917 if (!ISALNUM ((unsigned char)*r
))
1920 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1921 output_file
, prefix
);
1923 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1924 initname
= xmalloc (strlen (prefix
) + sizeof (INIT_NAME_FORMAT
) - 2);
1925 sprintf (initname
, INIT_NAME_FORMAT
, prefix
);
1927 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1928 fininame
= xmalloc (strlen (prefix
) + sizeof (FINI_NAME_FORMAT
) - 2);
1929 sprintf (fininame
, FINI_NAME_FORMAT
, prefix
);
1933 /* Write the tables as C code */
1935 fprintf (stream
, "static int count;\n");
1936 fprintf (stream
, "typedef void entry_pt();\n");
1937 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1941 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1943 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1944 write_list (stream
, "\t\t&", frame_tables
.first
);
1945 fprintf (stream
, "\t0\n};\n");
1947 /* This must match what's in frame.h. */
1948 fprintf (stream
, "struct object {\n");
1949 fprintf (stream
, " void *pc_begin;\n");
1950 fprintf (stream
, " void *pc_end;\n");
1951 fprintf (stream
, " void *fde_begin;\n");
1952 fprintf (stream
, " void *fde_array;\n");
1953 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1954 fprintf (stream
, " struct object *next;\n");
1955 fprintf (stream
, "};\n");
1957 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1958 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1960 fprintf (stream
, "static void reg_frame () {\n");
1961 fprintf (stream
, "\tstatic struct object ob;\n");
1962 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1963 fprintf (stream
, "\t}\n");
1965 fprintf (stream
, "static void dereg_frame () {\n");
1966 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1967 fprintf (stream
, "\t}\n");
1970 fprintf (stream
, "void %s() {\n", initname
);
1971 if (constructors
.number
> 0 || frames
)
1973 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1974 write_list (stream
, "\t\t", constructors
.first
);
1976 fprintf (stream
, "\treg_frame,\n");
1977 fprintf (stream
, "\t};\n");
1978 fprintf (stream
, "\tentry_pt **p;\n");
1979 fprintf (stream
, "\tif (count++ != 0) return;\n");
1980 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1981 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1984 fprintf (stream
, "\t++count;\n");
1985 fprintf (stream
, "}\n");
1986 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1987 fprintf (stream
, "void %s() {\n", fininame
);
1988 if (destructors
.number
> 0 || frames
)
1990 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1991 write_list (stream
, "\t\t", destructors
.first
);
1993 fprintf (stream
, "\tdereg_frame,\n");
1994 fprintf (stream
, "\t};\n");
1995 fprintf (stream
, "\tentry_pt **p;\n");
1996 fprintf (stream
, "\tif (--count != 0) return;\n");
1997 fprintf (stream
, "\tp = dtors;\n");
1998 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
1999 destructors
.number
+ frames
);
2001 fprintf (stream
, "}\n");
2005 fprintf (stream
, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname
);
2006 fprintf (stream
, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame
);
2010 /* Write the constructor/destructor tables. */
2012 #ifndef LD_INIT_SWITCH
2014 write_c_file_glob (stream
, name
)
2016 const char *name ATTRIBUTE_UNUSED
;
2018 /* Write the tables as C code */
2020 int frames
= (frame_tables
.number
> 0);
2022 fprintf (stream
, "typedef void entry_pt();\n\n");
2024 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
2028 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
2030 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
2031 write_list (stream
, "\t\t&", frame_tables
.first
);
2032 fprintf (stream
, "\t0\n};\n");
2034 /* This must match what's in frame.h. */
2035 fprintf (stream
, "struct object {\n");
2036 fprintf (stream
, " void *pc_begin;\n");
2037 fprintf (stream
, " void *pc_end;\n");
2038 fprintf (stream
, " void *fde_begin;\n");
2039 fprintf (stream
, " void *fde_array;\n");
2040 fprintf (stream
, " __SIZE_TYPE__ count;\n");
2041 fprintf (stream
, " struct object *next;\n");
2042 fprintf (stream
, "};\n");
2044 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2045 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2047 fprintf (stream
, "static void reg_frame () {\n");
2048 fprintf (stream
, "\tstatic struct object ob;\n");
2049 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2050 fprintf (stream
, "\t}\n");
2052 fprintf (stream
, "static void dereg_frame () {\n");
2053 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2054 fprintf (stream
, "\t}\n");
2057 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2058 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2059 write_list (stream
, "\t", constructors
.first
);
2061 fprintf (stream
, "\treg_frame,\n");
2062 fprintf (stream
, "\t0\n};\n\n");
2064 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2066 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2067 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2068 write_list (stream
, "\t", destructors
.first
);
2070 fprintf (stream
, "\tdereg_frame,\n");
2071 fprintf (stream
, "\t0\n};\n\n");
2073 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2074 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2076 #endif /* ! LD_INIT_SWITCH */
2079 write_c_file (stream
, name
)
2083 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2084 #ifndef LD_INIT_SWITCH
2086 write_c_file_glob (stream
, name
);
2089 write_c_file_stat (stream
, name
);
2090 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2093 #ifdef COLLECT_EXPORT_LIST
2095 write_aix_file (stream
, list
)
2099 for (; list
; list
= list
->next
)
2101 fputs (list
->name
, stream
);
2102 putc ('\n', stream
);
2107 #ifdef OBJECT_FORMAT_NONE
2109 /* Generic version to scan the name list of the loaded program for
2110 the symbols g++ uses for static constructors and destructors.
2112 The constructor table begins at __CTOR_LIST__ and contains a count
2113 of the number of pointers (or -1 if the constructors are built in a
2114 separate section by the linker), followed by the pointers to the
2115 constructor functions, terminated with a null pointer. The
2116 destructor table has the same format, and begins at __DTOR_LIST__. */
2119 scan_prog_file (prog_name
, which_pass
)
2120 const char *prog_name
;
2121 enum pass which_pass
;
2123 void (*int_handler
) ();
2124 void (*quit_handler
) ();
2125 char *real_nm_argv
[4];
2126 const char **nm_argv
= (const char **) real_nm_argv
;
2133 if (which_pass
== PASS_SECOND
)
2136 /* If we do not have an `nm', complain. */
2137 if (nm_file_name
== 0)
2138 fatal ("cannot find `nm'");
2140 nm_argv
[argc
++] = nm_file_name
;
2141 if (NM_FLAGS
[0] != '\0')
2142 nm_argv
[argc
++] = NM_FLAGS
;
2144 nm_argv
[argc
++] = prog_name
;
2145 nm_argv
[argc
++] = (char *) 0;
2147 if (pipe (pipe_fd
) < 0)
2148 fatal_perror ("pipe");
2150 inf
= fdopen (pipe_fd
[0], "r");
2151 if (inf
== (FILE *) 0)
2152 fatal_perror ("fdopen");
2154 /* Trace if needed. */
2157 const char **p_argv
;
2160 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2161 fprintf (stderr
, " %s", str
);
2163 fprintf (stderr
, "\n");
2169 /* Spawn child nm on pipe */
2172 fatal_perror (VFORK_STRING
);
2174 if (pid
== 0) /* child context */
2177 if (dup2 (pipe_fd
[1], 1) < 0)
2178 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2180 if (close (pipe_fd
[0]) < 0)
2181 fatal_perror ("close %d", pipe_fd
[0]);
2183 if (close (pipe_fd
[1]) < 0)
2184 fatal_perror ("close %d", pipe_fd
[1]);
2186 execv (nm_file_name
, real_nm_argv
);
2187 fatal_perror ("execvp %s", nm_file_name
);
2190 /* Parent context from here on. */
2191 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
2193 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
2196 if (close (pipe_fd
[1]) < 0)
2197 fatal_perror ("close %d", pipe_fd
[1]);
2200 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2202 /* Read each line of nm output. */
2203 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2208 /* If it contains a constructor or destructor name, add the name
2209 to the appropriate list. */
2211 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2212 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2219 /* Find the end of the symbol name.
2220 Do not include `|', because Encore nm can tack that on the end. */
2221 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2227 switch (is_ctor_dtor (name
))
2230 if (which_pass
!= PASS_LIB
)
2231 add_to_list (&constructors
, name
);
2235 if (which_pass
!= PASS_LIB
)
2236 add_to_list (&destructors
, name
);
2240 if (which_pass
!= PASS_LIB
)
2241 fatal ("init function found in object %s", prog_name
);
2242 #ifndef LD_INIT_SWITCH
2243 add_to_list (&constructors
, name
);
2248 if (which_pass
!= PASS_LIB
)
2249 fatal ("fini function found in object %s", prog_name
);
2250 #ifndef LD_FINI_SWITCH
2251 add_to_list (&destructors
, name
);
2256 if (which_pass
!= PASS_LIB
)
2257 add_to_list (&frame_tables
, name
);
2260 default: /* not a constructor or destructor */
2265 fprintf (stderr
, "\t%s\n", buf
);
2269 fprintf (stderr
, "\n");
2271 if (fclose (inf
) != 0)
2272 fatal_perror ("fclose");
2274 do_wait (nm_file_name
);
2276 signal (SIGINT
, int_handler
);
2278 signal (SIGQUIT
, quit_handler
);
2282 #if SUNOS4_SHARED_LIBRARIES
2284 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2285 that the output file depends upon and their initialization/finalization
2286 routines, if any. */
2291 #include <sys/mman.h>
2292 #include <sys/param.h>
2294 #include <sys/dir.h>
2296 /* pointers to the object file */
2297 unsigned object
; /* address of memory mapped file */
2298 unsigned objsize
; /* size of memory mapped to file */
2299 char * code
; /* pointer to code segment */
2300 char * data
; /* pointer to data segment */
2301 struct nlist
*symtab
; /* pointer to symbol table */
2302 struct link_dynamic
*ld
;
2303 struct link_dynamic_2
*ld_2
;
2304 struct head libraries
;
2306 /* Map the file indicated by NAME into memory and store its address. */
2308 static void mapfile
PROTO ((const char *));
2316 if ((fp
= open (name
, O_RDONLY
)) == -1)
2317 fatal ("unable to open file '%s'", name
);
2318 if (fstat (fp
, &s
) == -1)
2319 fatal ("unable to stat file '%s'", name
);
2321 objsize
= s
.st_size
;
2322 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2324 if (object
== (unsigned)-1)
2325 fatal ("unable to mmap file '%s'", name
);
2330 /* Helpers for locatelib. */
2332 static const char *libname
;
2334 static int libselect
PROTO ((struct direct
*));
2340 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2343 /* If one file has an additional numeric extension past LIBNAME, then put
2344 that one first in the sort. If both files have additional numeric
2345 extensions, then put the one with the higher number first in the sort.
2347 We must verify that the extension is numeric, because Sun saves the
2348 original versions of patched libraries with a .FCS extension. Files with
2349 invalid extensions must go last in the sort, so that they will not be used. */
2350 static int libcompare
PROTO ((struct direct
**, struct direct
**));
2354 struct direct
**d1
, **d2
;
2356 int i1
, i2
= strlen (libname
);
2357 char *e1
= (*d1
)->d_name
+ i2
;
2358 char *e2
= (*d2
)->d_name
+ i2
;
2360 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2361 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2365 i1
= strtol (e1
, &e1
, 10);
2366 i2
= strtol (e2
, &e2
, 10);
2373 /* It has a valid numeric extension, prefer this one. */
2374 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2376 /* It has a invalid numeric extension, must prefer the other one. */
2382 /* It has a valid numeric extension, prefer this one. */
2383 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2385 /* It has a invalid numeric extension, must prefer the other one. */
2393 /* Given the name NAME of a dynamic dependency, find its pathname and add
2394 it to the list of libraries. */
2395 static void locatelib
PROTO ((const char *));
2401 static const char **l
;
2403 char buf
[MAXPATHLEN
];
2411 /* counting elements in array, need 1 extra for null */
2413 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2417 for (; *ld_rules
!= 0; ld_rules
++)
2418 if (*ld_rules
== ':')
2420 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2421 ldr
= (char *) xmalloc (strlen (ld_rules
) + 1);
2422 strcpy (ldr
, ld_rules
);
2424 p
= getenv ("LD_LIBRARY_PATH");
2429 for (q
= p
; *q
!= 0; q
++)
2432 q
= (char *) xmalloc (strlen (p
) + 1);
2435 l
= (const char **) xmalloc ((cnt
+ 3) * sizeof (char *));
2440 for (; *ldr
!= 0; ldr
++)
2450 for (; *q
!= 0; q
++)
2457 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2460 *pp
++ = "/usr/local/lib";
2464 for (pp
= l
; *pp
!= 0 ; pp
++)
2466 struct direct
**namelist
;
2468 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2470 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2471 add_to_list (&libraries
, buf
);
2473 fprintf (stderr
, "%s\n", buf
);
2480 notice ("not found\n");
2482 fatal ("dynamic dependency %s not found", name
);
2486 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2487 that it depends upon and any constructors or destructors they contain. */
2490 scan_libraries (prog_name
)
2491 const char *prog_name
;
2493 struct exec
*header
;
2495 struct link_object
*lo
;
2496 char buff
[MAXPATHLEN
];
2499 mapfile (prog_name
);
2500 header
= (struct exec
*)object
;
2501 if (N_BADMAG (*header
))
2502 fatal ("bad magic number in file '%s'", prog_name
);
2503 if (header
->a_dynamic
== 0)
2506 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2507 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2508 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2510 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2513 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2519 ld
= (struct link_dynamic
*) data
;
2524 notice ("dynamic dependencies.\n");
2526 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2527 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2528 lo
= (struct link_object
*) lo
->lo_next
)
2531 lo
= (struct link_object
*) ((long) lo
+ code
);
2532 name
= (char *) (code
+ lo
->lo_name
);
2536 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2537 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2543 fprintf (stderr
, "\t%s\n", name
);
2544 add_to_list (&libraries
, name
);
2549 fprintf (stderr
, "\n");
2551 /* now iterate through the library list adding their symbols to
2553 for (list
= libraries
.first
; list
; list
= list
->next
)
2554 scan_prog_file (list
->name
, PASS_LIB
);
2557 #else /* SUNOS4_SHARED_LIBRARIES */
2560 /* Use the List Dynamic Dependencies program to find shared libraries that
2561 the output file depends upon and their initialization/finalization
2562 routines, if any. */
2565 scan_libraries (prog_name
)
2566 const char *prog_name
;
2568 static struct head libraries
; /* list of shared libraries found */
2570 void (*int_handler
) ();
2571 void (*quit_handler
) ();
2573 const char **ldd_argv
= (const char **) real_ldd_argv
;
2580 /* If we do not have an `ldd', complain. */
2581 if (ldd_file_name
== 0)
2583 error ("cannot find `ldd'");
2587 ldd_argv
[argc
++] = ldd_file_name
;
2588 ldd_argv
[argc
++] = prog_name
;
2589 ldd_argv
[argc
++] = (char *) 0;
2591 if (pipe (pipe_fd
) < 0)
2592 fatal_perror ("pipe");
2594 inf
= fdopen (pipe_fd
[0], "r");
2595 if (inf
== (FILE *) 0)
2596 fatal_perror ("fdopen");
2598 /* Trace if needed. */
2601 const char **p_argv
;
2604 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2605 fprintf (stderr
, " %s", str
);
2607 fprintf (stderr
, "\n");
2613 /* Spawn child ldd on pipe */
2616 fatal_perror (VFORK_STRING
);
2618 if (pid
== 0) /* child context */
2621 if (dup2 (pipe_fd
[1], 1) < 0)
2622 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2624 if (close (pipe_fd
[0]) < 0)
2625 fatal_perror ("close %d", pipe_fd
[0]);
2627 if (close (pipe_fd
[1]) < 0)
2628 fatal_perror ("close %d", pipe_fd
[1]);
2630 execv (ldd_file_name
, real_ldd_argv
);
2631 fatal_perror ("execv %s", ldd_file_name
);
2634 /* Parent context from here on. */
2635 int_handler
= (void (*) ()) signal (SIGINT
, SIG_IGN
);
2637 quit_handler
= (void (*) ()) signal (SIGQUIT
, SIG_IGN
);
2640 if (close (pipe_fd
[1]) < 0)
2641 fatal_perror ("close %d", pipe_fd
[1]);
2644 notice ("\nldd output with constructors/destructors.\n");
2646 /* Read each line of ldd output. */
2647 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2650 char *name
, *end
, *p
= buf
;
2652 /* Extract names of libraries and add to list. */
2653 PARSE_LDD_OUTPUT (p
);
2658 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2659 fatal ("dynamic dependency %s not found", buf
);
2661 /* Find the end of the symbol name. */
2663 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2668 if (access (name
, R_OK
) == 0)
2669 add_to_list (&libraries
, name
);
2671 fatal ("unable to open dynamic dependency '%s'", buf
);
2674 fprintf (stderr
, "\t%s\n", buf
);
2677 fprintf (stderr
, "\n");
2679 if (fclose (inf
) != 0)
2680 fatal_perror ("fclose");
2682 do_wait (ldd_file_name
);
2684 signal (SIGINT
, int_handler
);
2686 signal (SIGQUIT
, quit_handler
);
2689 /* now iterate through the library list adding their symbols to
2691 for (list
= libraries
.first
; list
; list
= list
->next
)
2692 scan_prog_file (list
->name
, PASS_LIB
);
2695 #endif /* LDD_SUFFIX */
2696 #endif /* SUNOS4_SHARED_LIBRARIES */
2698 #endif /* OBJECT_FORMAT_NONE */
2702 * COFF specific stuff.
2705 #ifdef OBJECT_FORMAT_COFF
2707 #if defined(EXTENDED_COFF)
2708 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2709 # define GCC_SYMENT SYMR
2710 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2711 # define GCC_SYMINC(X) (1)
2712 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2713 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2715 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2716 # define GCC_SYMENT SYMENT
2717 # define GCC_OK_SYMBOL(X) \
2718 (((X).n_sclass == C_EXT) && \
2719 ((X).n_scnum > N_UNDEF) && \
2721 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2722 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2723 # define GCC_UNDEF_SYMBOL(X) \
2724 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2725 # define GCC_SYMINC(X) ((X).n_numaux+1)
2726 # define GCC_SYMZERO(X) 0
2727 # define GCC_CHECK_HDR(X) \
2728 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2729 || (HEADER (X).f_magic == 0757 && aix64_flag))
2732 extern char *ldgetname ();
2734 /* COFF version to scan the name list of the loaded program for
2735 the symbols g++ uses for static constructors and destructors.
2737 The constructor table begins at __CTOR_LIST__ and contains a count
2738 of the number of pointers (or -1 if the constructors are built in a
2739 separate section by the linker), followed by the pointers to the
2740 constructor functions, terminated with a null pointer. The
2741 destructor table has the same format, and begins at __DTOR_LIST__. */
2744 scan_prog_file (prog_name
, which_pass
)
2745 const char *prog_name
;
2746 enum pass which_pass
;
2748 LDFILE
*ldptr
= NULL
;
2749 int sym_index
, sym_count
;
2751 #ifdef COLLECT_EXPORT_LIST
2752 /* Should we generate an import list for given prog_name? */
2753 int import_flag
= (which_pass
== PASS_OBJ
? 0 : use_import_list (prog_name
));
2756 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2759 #ifdef COLLECT_EXPORT_LIST
2760 /* We do not need scanning for some standard C libraries. */
2761 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2764 /* On AIX we have a loop, because there is not much difference
2765 between an object and an archive. This trick allows us to
2766 eliminate scan_libraries() function. */
2770 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2771 non-const char * filename parameter, even though it will not
2772 modify that string. So we must cast away const-ness here,
2773 which will cause -Wcast-qual to burp. */
2774 if ((ldptr
= ldopen ((char *)prog_name
, ldptr
)) != NULL
)
2776 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2777 fatal ("%s: not a COFF file", prog_name
);
2779 if (GCC_CHECK_HDR (ldptr
))
2781 sym_count
= GCC_SYMBOLS (ldptr
);
2782 sym_index
= GCC_SYMZERO (ldptr
);
2784 #ifdef COLLECT_EXPORT_LIST
2785 /* Is current archive member a shared object? */
2786 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2789 while (sym_index
< sym_count
)
2793 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2795 sym_index
+= GCC_SYMINC (symbol
);
2797 if (GCC_OK_SYMBOL (symbol
))
2801 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2802 continue; /* should never happen */
2804 #ifdef XCOFF_DEBUGGING_INFO
2805 /* All AIX function names have a duplicate entry
2806 beginning with a dot. */
2811 switch (is_ctor_dtor (name
))
2814 if (! is_shared
) 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
);
2829 if (! is_shared
) add_to_list (&destructors
, name
);
2830 #ifdef COLLECT_EXPORT_LIST
2831 if (which_pass
== PASS_OBJ
)
2832 add_to_list (&exports
, name
);
2833 /* If this symbol was undefined and we are building
2834 an import list, we should add a symbol to this
2838 && is_in_list (name
, undefined
.first
))
2839 add_to_list (&imports
, name
);
2843 #ifdef COLLECT_EXPORT_LIST
2846 add_to_list (&constructors
, name
);
2851 add_to_list (&destructors
, name
);
2857 add_to_list (&frame_tables
, name
);
2860 default: /* not a constructor or destructor */
2861 #ifdef COLLECT_EXPORT_LIST
2862 /* If we are building a shared object on AIX we need
2863 to explicitly export all global symbols or add
2864 them to import list. */
2867 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2868 add_to_list (&exports
, name
);
2869 else if (! is_shared
&& which_pass
== PASS_FIRST
2871 && is_in_list(name
, undefined
.first
))
2872 add_to_list (&imports
, name
);
2878 #if !defined(EXTENDED_COFF)
2880 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2881 symbol
.n_scnum
, symbol
.n_sclass
,
2882 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2887 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2888 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2891 #ifdef COLLECT_EXPORT_LIST
2892 /* If we are building a shared object we should collect
2893 information about undefined symbols for later
2894 import list generation. */
2895 else if (shared_obj
&& GCC_UNDEF_SYMBOL (symbol
))
2899 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2900 continue; /* should never happen */
2902 /* All AIX function names have a duplicate entry
2903 beginning with a dot. */
2906 add_to_list (&undefined
, name
);
2911 #ifdef COLLECT_EXPORT_LIST
2914 /* If archive contains both 32-bit and 64-bit objects,
2915 we want to skip objects in other mode so mismatch normal. */
2917 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2918 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2924 fatal ("%s: cannot open as COFF file", prog_name
);
2926 #ifdef COLLECT_EXPORT_LIST
2927 /* On AIX loop continues while there are more members in archive. */
2929 while (ldclose (ldptr
) == FAILURE
);
2931 /* Otherwise we simply close ldptr. */
2932 (void) ldclose(ldptr
);
2937 #ifdef COLLECT_EXPORT_LIST
2939 /* This new function is used to decide whether we should
2940 generate import list for an object or to use it directly. */
2942 use_import_list (prog_name
)
2943 const char *prog_name
;
2947 /* If we do not build a shared object then import list should not be used. */
2948 if (! shared_obj
) return 0;
2950 /* Currently we check only for libgcc, but this can be changed in future. */
2951 p
= strstr (prog_name
, "libgcc.a");
2952 if (p
!= 0 && (strlen (p
) == sizeof ("libgcc.a") - 1))
2957 /* Given a library name without "lib" prefix, this function
2958 returns a full library name including a path. */
2960 resolve_lib_name (name
)
2966 for (i
= 0; libpaths
[i
]; i
++)
2967 if (libpaths
[i
]->max_len
> l
)
2968 l
= libpaths
[i
]->max_len
;
2970 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2972 for (i
= 0; libpaths
[i
]; i
++)
2974 struct prefix_list
*list
= libpaths
[i
]->plist
;
2975 for (; list
; list
= list
->next
)
2977 for (j
= 0; libexts
[j
]; j
++)
2979 /* The following lines are needed because path_prefix list
2980 may contain directories both with trailing '/' and
2983 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
2985 sprintf (lib_buf
, "%s%slib%s.%s",
2986 list
->prefix
, p
, name
, libexts
[j
]);
2987 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
2988 if (file_exists (lib_buf
))
2990 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
2997 fprintf (stderr
, "not found\n");
2999 fatal ("Library lib%s not found", name
);
3003 /* Array of standard AIX libraries which should not
3004 be scanned for ctors/dtors. */
3005 static const char *aix_std_libs
[] = {
3010 "/usr/lib/libc_r.a",
3011 "/usr/lib/threads/libc.a",
3012 "/usr/ccs/lib/libc.a",
3013 "/usr/ccs/lib/libc_r.a",
3017 /* This function checks the filename and returns 1
3018 if this name matches the location of a standard AIX library. */
3020 ignore_library (name
)
3023 const char **p
= &aix_std_libs
[0];
3024 while (*p
++ != NULL
)
3025 if (! strcmp (name
, *p
)) return 1;
3031 #endif /* OBJECT_FORMAT_COFF */
3035 * OSF/rose specific stuff.
3038 #ifdef OBJECT_FORMAT_ROSE
3040 /* Union of the various load commands */
3042 typedef union load_union
3044 ldc_header_t hdr
; /* common header */
3045 load_cmd_map_command_t map
; /* map indexing other load cmds */
3046 interpreter_command_t iprtr
; /* interpreter pathname */
3047 strings_command_t str
; /* load commands strings section */
3048 region_command_t region
; /* region load command */
3049 reloc_command_t reloc
; /* relocation section */
3050 package_command_t pkg
; /* package load command */
3051 symbols_command_t sym
; /* symbol sections */
3052 entry_command_t ent
; /* program start section */
3053 gen_info_command_t info
; /* object information */
3054 func_table_command_t func
; /* function constructors/destructors */
3057 /* Structure to point to load command and data section in memory. */
3059 typedef struct load_all
3061 load_union_t
*load
; /* load command */
3062 char *section
; /* pointer to section */
3065 /* Structure to contain information about a file mapped into memory. */
3069 char *start
; /* start of map */
3070 char *name
; /* filename */
3071 long size
; /* size of the file */
3072 long rounded_size
; /* size rounded to page boundary */
3073 int fd
; /* file descriptor */
3074 int rw
; /* != 0 if opened read/write */
3075 int use_mmap
; /* != 0 if mmap'ed */
3078 extern int decode_mach_o_hdr ();
3079 extern int encode_mach_o_hdr ();
3081 static void add_func_table
PROTO((mo_header_t
*, load_all_t
*,
3082 symbol_info_t
*, int));
3083 static void print_header
PROTO((mo_header_t
*));
3084 static void print_load_command
PROTO((load_union_t
*, size_t, int));
3085 static void bad_header
PROTO((int));
3086 static struct file_info
*read_file
PROTO((const char *, int, int));
3087 static void end_file
PROTO((struct file_info
*));
3089 /* OSF/rose specific version to scan the name list of the loaded
3090 program for the symbols g++ uses for static constructors and
3093 The constructor table begins at __CTOR_LIST__ and contains a count
3094 of the number of pointers (or -1 if the constructors are built in a
3095 separate section by the linker), followed by the pointers to the
3096 constructor functions, terminated with a null pointer. The
3097 destructor table has the same format, and begins at __DTOR_LIST__. */
3100 scan_prog_file (prog_name
, which_pass
)
3101 const char *prog_name
;
3102 enum pass which_pass
;
3106 load_all_t
*load_array
;
3107 load_all_t
*load_end
;
3108 load_all_t
*load_cmd
;
3109 int symbol_load_cmds
;
3115 struct file_info
*obj_file
;
3117 mo_lcid_t cmd_strings
= -1;
3118 symbol_info_t
*main_sym
= 0;
3119 int rw
= (which_pass
!= PASS_FIRST
);
3121 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3123 fatal_perror ("open %s", prog_name
);
3125 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3126 obj
= obj_file
->start
;
3128 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3129 if (status
!= MO_HDR_CONV_SUCCESS
)
3130 bad_header (status
);
3133 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3134 since the hardware will automatically swap bytes for us on loading little endian
3137 #ifndef CROSS_COMPILE
3138 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3139 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3140 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3141 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3142 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3143 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3144 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3146 fatal ("incompatibilities between object file & expected values");
3151 print_header (&hdr
);
3153 offset
= hdr
.moh_first_cmd_off
;
3154 load_end
= load_array
3155 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3157 /* Build array of load commands, calculating the offsets */
3158 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3160 load_union_t
*load_hdr
; /* load command header */
3162 load_cmd
= load_end
++;
3163 load_hdr
= (load_union_t
*) (obj
+ offset
);
3165 /* If modifying the program file, copy the header. */
3168 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3169 bcopy ((char *)load_hdr
, (char *)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
3172 /* null out old command map, because we will rewrite at the end. */
3173 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3175 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3176 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3180 load_cmd
->load
= load_hdr
;
3181 if (load_hdr
->hdr
.ldci_section_off
> 0)
3182 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3185 print_load_command (load_hdr
, offset
, i
);
3187 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3190 /* If the last command is the load command map and is not undefined,
3191 decrement the count of load commands. */
3192 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3195 hdr
.moh_n_load_cmds
--;
3198 /* Go through and process each symbol table section. */
3199 symbol_load_cmds
= 0;
3200 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3202 load_union_t
*load_hdr
= load_cmd
->load
;
3204 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3210 const char *kind
= "unknown";
3212 switch (load_hdr
->sym
.symc_kind
)
3214 case SYMC_IMPORTS
: kind
= "imports"; break;
3215 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3216 case SYMC_STABS
: kind
= "stabs"; break;
3219 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3220 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3223 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3226 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3227 if (str_sect
== (char *) 0)
3228 fatal ("string section missing");
3230 if (load_cmd
->section
== (char *) 0)
3231 fatal ("section pointer missing");
3233 num_syms
= load_hdr
->sym
.symc_nentries
;
3234 for (i
= 0; i
< num_syms
; i
++)
3236 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3237 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3244 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3246 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3256 switch (is_ctor_dtor (name
))
3259 add_to_list (&constructors
, name
);
3263 add_to_list (&destructors
, name
);
3266 default: /* not a constructor or destructor */
3272 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3273 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3278 if (symbol_load_cmds
== 0)
3279 fatal ("no symbol table found");
3281 /* Update the program file now, rewrite header and load commands. At present,
3282 we assume that there is enough space after the last load command to insert
3283 one more. Since the first section written out is page aligned, and the
3284 number of load commands is small, this is ok for the present. */
3288 load_union_t
*load_map
;
3291 if (cmd_strings
== -1)
3292 fatal ("no cmd_strings found");
3294 /* Add __main to initializer list.
3295 If we are building a program instead of a shared library, do not
3296 do anything, since in the current version, you cannot do mallocs
3297 and such in the constructors. */
3299 if (main_sym
!= (symbol_info_t
*) 0
3300 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3301 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3304 notice ("\nUpdating header and load commands.\n\n");
3306 hdr
.moh_n_load_cmds
++;
3307 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3309 /* Create new load command map. */
3311 notice ("load command map, %d cmds, new size %ld.\n",
3312 (int) hdr
.moh_n_load_cmds
, (long) size
);
3314 load_map
= (load_union_t
*) xcalloc (1, size
);
3315 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3316 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3317 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3318 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3319 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3321 offset
= hdr
.moh_first_cmd_off
;
3322 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3324 load_map
->map
.lcm_map
[i
] = offset
;
3325 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3326 hdr
.moh_load_map_cmd_off
= offset
;
3328 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3331 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3334 print_header (&hdr
);
3337 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3338 if (status
!= MO_HDR_CONV_SUCCESS
)
3339 bad_header (status
);
3342 notice ("writing load commands.\n\n");
3344 /* Write load commands */
3345 offset
= hdr
.moh_first_cmd_off
;
3346 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3348 load_union_t
*load_hdr
= load_array
[i
].load
;
3349 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3352 print_load_command (load_hdr
, offset
, i
);
3354 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3359 end_file (obj_file
);
3361 if (close (prog_fd
))
3362 fatal_perror ("close %s", prog_name
);
3365 fprintf (stderr
, "\n");
3369 /* Add a function table to the load commands to call a function
3370 on initiation or termination of the process. */
3373 add_func_table (hdr_p
, load_array
, sym
, type
)
3374 mo_header_t
*hdr_p
; /* pointer to global header */
3375 load_all_t
*load_array
; /* array of ptrs to load cmds */
3376 symbol_info_t
*sym
; /* pointer to symbol entry */
3377 int type
; /* fntc_type value */
3379 /* Add a new load command. */
3380 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3381 int load_index
= num_cmds
- 1;
3382 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3383 load_union_t
*ptr
= xcalloc (1, size
);
3384 load_all_t
*load_cmd
;
3387 /* Set the unresolved address bit in the header to force the loader to be
3388 used, since kernel exec does not call the initialization functions. */
3389 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3391 load_cmd
= &load_array
[load_index
];
3392 load_cmd
->load
= ptr
;
3393 load_cmd
->section
= (char *) 0;
3395 /* Fill in func table load command. */
3396 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3397 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3398 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3399 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3400 ptr
->func
.fntc_type
= type
;
3401 ptr
->func
.fntc_nentries
= 1;
3403 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3404 /* Is the symbol already expressed as (region, offset)? */
3405 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3407 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3408 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3411 /* If not, figure out which region it's in. */
3414 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3417 for (i
= 0; i
< load_index
; i
++)
3419 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3421 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3423 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3424 && addr
>= region_ptr
->regc_addr
.vm_addr
3425 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3427 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3428 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3436 fatal ("could not convert 0x%l.8x into a region", addr
);
3440 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3441 type
== FNTC_INITIALIZATION
? "init" : "term",
3442 (int) ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3443 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3444 (long) ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3449 /* Print the global header for an OSF/rose object. */
3452 print_header (hdr_ptr
)
3453 mo_header_t
*hdr_ptr
;
3455 fprintf (stderr
, "\nglobal header:\n");
3456 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3457 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3458 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3459 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3460 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3461 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3462 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3463 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3464 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3465 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3466 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3467 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3468 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3469 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3470 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3472 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3473 fprintf (stderr
, ", relocatable");
3475 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3476 fprintf (stderr
, ", linkable");
3478 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3479 fprintf (stderr
, ", execable");
3481 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3482 fprintf (stderr
, ", executable");
3484 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3485 fprintf (stderr
, ", unresolved");
3487 fprintf (stderr
, "\n\n");
3492 /* Print a short summary of a load command. */
3495 print_load_command (load_hdr
, offset
, number
)
3496 load_union_t
*load_hdr
;
3500 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3501 const char *type_str
= (char *) 0;
3505 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3506 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3507 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3508 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3509 case LDC_REGION
: type_str
= "REGION"; break;
3510 case LDC_RELOC
: type_str
= "RELOC"; break;
3511 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3512 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3513 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3514 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3515 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3519 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3521 (long) load_hdr
->hdr
.ldci_cmd_size
,
3523 (long) load_hdr
->hdr
.ldci_section_off
,
3524 (long) load_hdr
->hdr
.ldci_section_len
);
3526 if (type_str
== (char *) 0)
3527 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3529 else if (type
!= LDC_REGION
)
3530 fprintf (stderr
, ", ty: %s\n", type_str
);
3534 const char *region
= "";
3535 switch (load_hdr
->region
.regc_usage_type
)
3537 case REG_TEXT_T
: region
= ", .text"; break;
3538 case REG_DATA_T
: region
= ", .data"; break;
3539 case REG_BSS_T
: region
= ", .bss"; break;
3540 case REG_GLUE_T
: region
= ", .glue"; break;
3541 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3542 case REG_RDATA_T
: region
= ", .rdata"; break;
3543 case REG_SDATA_T
: region
= ", .sdata"; break;
3544 case REG_SBSS_T
: region
= ", .sbss"; break;
3548 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3550 (long) load_hdr
->region
.regc_vm_addr
,
3551 (long) load_hdr
->region
.regc_vm_size
,
3559 /* Fatal error when {en,de}code_mach_o_header fails. */
3567 case MO_ERROR_BAD_MAGIC
: fatal ("bad magic number");
3568 case MO_ERROR_BAD_HDR_VERS
: fatal ("bad header version");
3569 case MO_ERROR_BAD_RAW_HDR_VERS
: fatal ("bad raw header version");
3570 case MO_ERROR_BUF2SML
: fatal ("raw header buffer too small");
3571 case MO_ERROR_OLD_RAW_HDR_FILE
: fatal ("old raw header file");
3572 case MO_ERROR_UNSUPPORTED_VERS
: fatal ("unsupported version");
3574 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3579 /* Read a file into a memory buffer. */
3581 static struct file_info
*
3582 read_file (name
, fd
, rw
)
3583 const char *name
; /* filename */
3584 int fd
; /* file descriptor */
3585 int rw
; /* read/write */
3587 struct stat stat_pkt
;
3588 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3590 static int page_size
;
3593 if (fstat (fd
, &stat_pkt
) < 0)
3594 fatal_perror ("fstat %s", name
);
3597 p
->size
= stat_pkt
.st_size
;
3598 p
->rounded_size
= stat_pkt
.st_size
;
3604 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3607 page_size
= sysconf (_SC_PAGE_SIZE
);
3609 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3610 p
->start
= mmap ((caddr_t
) 0,
3611 (rw
) ? p
->rounded_size
: p
->size
,
3612 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3613 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3617 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3621 #endif /* USE_MMAP */
3626 fprintf (stderr
, "read %s\n", name
);
3629 p
->start
= xmalloc (p
->size
);
3630 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3631 fatal_perror ("lseek %s 0", name
);
3633 len
= read (fd
, p
->start
, p
->size
);
3635 fatal_perror ("read %s", name
);
3638 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3644 /* Do anything necessary to write a file back from memory. */
3648 struct file_info
*ptr
; /* file information block */
3656 fprintf (stderr
, "msync %s\n", ptr
->name
);
3658 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3659 fatal_perror ("msync %s", ptr
->name
);
3663 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3665 if (munmap (ptr
->start
, ptr
->size
))
3666 fatal_perror ("munmap %s", ptr
->name
);
3669 #endif /* USE_MMAP */
3676 fprintf (stderr
, "write %s\n", ptr
->name
);
3678 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3679 fatal_perror ("lseek %s 0", ptr
->name
);
3681 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3683 fatal_perror ("write %s", ptr
->name
);
3685 if (len
!= ptr
->size
)
3686 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3695 #endif /* OBJECT_FORMAT_ROSE */