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)
54 /* Obstack allocation and deallocation routines. */
55 #define obstack_chunk_alloc xmalloc
56 #define obstack_chunk_free free
58 extern char *make_temp_file
PROTO ((char *));
60 /* On certain systems, we have code that works by scanning the object file
61 directly. But this code uses system-specific header files and library
62 functions, so turn it off in a cross-compiler. Likewise, the names of
63 the utilities are not correct for a cross-compiler; we have to hope that
64 cross-versions are in the proper directories. */
67 #undef SUNOS4_SHARED_LIBRARIES
68 #undef OBJECT_FORMAT_COFF
69 #undef OBJECT_FORMAT_ROSE
71 #undef REAL_LD_FILE_NAME
72 #undef REAL_NM_FILE_NAME
73 #undef REAL_STRIP_FILE_NAME
76 /* If we cannot use a special method, use the ordinary one:
77 run nm to find what symbols are present.
78 In a cross-compiler, this means you need a cross nm,
79 but that is not quite as unpleasant as special headers. */
81 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
82 #define OBJECT_FORMAT_NONE
85 #ifdef OBJECT_FORMAT_COFF
94 /* Many versions of ldfcn.h define these. */
102 /* Some systems have an ISCOFF macro, but others do not. In some cases
103 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
104 that either do not have an ISCOFF macro in /usr/include or for those
105 where it is wrong. */
108 #define MY_ISCOFF(X) ISCOFF (X)
111 #endif /* OBJECT_FORMAT_COFF */
113 #ifdef OBJECT_FORMAT_ROSE
120 #include <sys/mman.h>
124 #include <mach_o_format.h>
125 #include <mach_o_header.h>
126 #include <mach_o_vals.h>
127 #include <mach_o_types.h>
129 #endif /* OBJECT_FORMAT_ROSE */
131 #ifdef OBJECT_FORMAT_NONE
133 /* Default flags to pass to nm. */
135 #define NM_FLAGS "-n"
138 #endif /* OBJECT_FORMAT_NONE */
140 /* Some systems use __main in a way incompatible with its use in gcc, in these
141 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
142 give the same symbol without quotes for an alternative entry point. You
143 must define both, or neither. */
145 #define NAME__MAIN "__main"
146 #define SYMBOL__MAIN __main
149 /* This must match tree.h. */
150 #define DEFAULT_INIT_PRIORITY 65535
152 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
153 #define SCAN_LIBRARIES
157 int do_collecting
= 1;
159 int do_collecting
= 0;
162 /* Linked lists of constructor and destructor names. */
178 /* Enumeration giving which pass this is for scanning the program file. */
181 PASS_FIRST
, /* without constructors */
182 PASS_OBJ
, /* individual objects */
183 PASS_LIB
, /* looking for shared libraries */
184 PASS_SECOND
/* with constructors linked in */
187 extern char *version_string
;
189 int vflag
; /* true if -v */
190 static int rflag
; /* true if -r */
191 static int strip_flag
; /* true if -s */
192 #ifdef COLLECT_EXPORT_LIST
193 static int export_flag
; /* true if -bE */
194 static int aix64_flag
; /* true if -b64 */
197 int debug
; /* true if -debug */
199 static int shared_obj
; /* true if -shared */
201 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
202 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
203 #ifdef COLLECT_EXPORT_LIST
204 static char *export_file
; /* <xxx>.x for AIX export list. */
205 static char *import_file
; /* <xxx>.p for AIX import list. */
207 char *ldout
; /* File for ld errors. */
208 static char *output_file
; /* Output file for ld. */
209 static char *nm_file_name
; /* pathname of nm */
211 static char *ldd_file_name
; /* pathname of ldd (or equivalent) */
213 static char *strip_file_name
; /* pathname of strip */
214 char *c_file_name
; /* pathname of gcc */
215 static char *initname
, *fininame
; /* names of init and fini funcs */
217 static struct head constructors
; /* list of constructors found */
218 static struct head destructors
; /* list of destructors found */
219 #ifdef COLLECT_EXPORT_LIST
220 static struct head exports
; /* list of exported symbols */
221 static struct head imports
; /* list of imported symbols */
222 static struct head undefined
; /* list of undefined symbols */
224 static struct head frame_tables
; /* list of frame unwind info tables */
226 struct obstack temporary_obstack
;
227 struct obstack permanent_obstack
;
228 char * temporary_firstobj
;
230 /* Defined in the automatically-generated underscore.c. */
231 extern int prepends_underscore
;
233 extern FILE *fdopen ();
235 #ifndef GET_ENV_PATH_LIST
236 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
239 /* Structure to hold all the directories in which to search for files to
244 char *prefix
; /* String to prepend to the path. */
245 struct prefix_list
*next
; /* Next in linked list. */
250 struct prefix_list
*plist
; /* List of prefixes to try */
251 int max_len
; /* Max length of a prefix in PLIST */
252 char *name
; /* Name of this list (used in config stuff) */
255 #ifdef COLLECT_EXPORT_LIST
256 /* Lists to keep libraries to be scanned for global constructors/destructors. */
257 static struct head libs
; /* list of libraries */
258 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
259 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
260 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
261 &libpath_lib_dirs
, NULL
};
262 static char *libexts
[3] = {"a", "so", NULL
}; /* possible library extentions */
265 void error
PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1
;
266 void fatal
PVPROTO((const char *, ...))
267 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN
;
268 void fatal_perror
PVPROTO((const char *, ...))
269 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN
;
270 static char *my_strerror
PROTO((int));
271 static const char *my_strsignal
PROTO((int));
272 static void handler
PROTO((int));
273 static int is_ctor_dtor
PROTO((char *));
274 static char *find_a_file
PROTO((struct path_prefix
*, char *));
275 static void add_prefix
PROTO((struct path_prefix
*, char *));
276 static void prefix_from_env
PROTO((char *, struct path_prefix
*));
277 static void prefix_from_string
PROTO((char *, struct path_prefix
*));
278 static void do_wait
PROTO((char *));
279 static void fork_execute
PROTO((char *, char **));
280 static void maybe_unlink
PROTO((char *));
281 static void add_to_list
PROTO((struct head
*, char *));
282 static int extract_init_priority
PROTO((char *));
283 static void sort_ids
PROTO((struct head
*));
284 static void write_list
PROTO((FILE *, char *, struct id
*));
285 #ifdef COLLECT_EXPORT_LIST
286 static void dump_list
PROTO((FILE *, char *, struct id
*));
289 static void dump_prefix_list
PROTO((FILE *, char *, struct prefix_list
*));
291 static void write_list_with_asm
PROTO((FILE *, char *, struct id
*));
292 static void write_c_file
PROTO((FILE *, char *));
293 static void scan_prog_file
PROTO((char *, enum pass
));
294 #ifdef SCAN_LIBRARIES
295 static void scan_libraries
PROTO((char *));
297 #ifdef COLLECT_EXPORT_LIST
298 static int is_in_list
PROTO((char *, struct id
*));
299 static void write_export_file
PROTO((FILE *));
300 static void write_import_file
PROTO((FILE *));
301 static char *resolve_lib_name
PROTO((char *));
302 static int use_import_list
PROTO((char *));
303 static int ignore_library
PROTO((char *));
319 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
322 close (fdtmp
[--fdx
]);
338 static char buffer
[30];
342 if (e
> 0 && e
< sys_nerr
)
343 return sys_errlist
[e
];
345 sprintf (buffer
, "Unknown error %d", e
);
354 #ifdef HAVE_STRSIGNAL
355 return strsignal (s
);
357 if (s
>= 0 && s
< NSIG
)
359 # ifdef NO_SYS_SIGLIST
360 static char buffer
[30];
362 sprintf (buffer
, "Unknown signal %d", s
);
365 return sys_siglist
[s
];
370 #endif /* HAVE_STRSIGNAL */
373 /* Delete tempfiles and exit function. */
376 collect_exit (status
)
379 if (c_file
!= 0 && c_file
[0])
380 maybe_unlink (c_file
);
382 if (o_file
!= 0 && o_file
[0])
383 maybe_unlink (o_file
);
385 #ifdef COLLECT_EXPORT_LIST
386 if (export_file
!= 0 && export_file
[0])
387 maybe_unlink (export_file
);
389 if (import_file
!= 0 && import_file
[0])
390 maybe_unlink (import_file
);
393 if (ldout
!= 0 && ldout
[0])
396 maybe_unlink (ldout
);
399 if (status
!= 0 && output_file
!= 0 && output_file
[0])
400 maybe_unlink (output_file
);
406 /* Die when sys call fails. */
409 fatal_perror
VPROTO((const char * string
, ...))
411 #ifndef ANSI_PROTOTYPES
417 VA_START (ap
, string
);
419 #ifndef ANSI_PROTOTYPES
420 string
= va_arg (ap
, const char *);
423 fprintf (stderr
, "collect2: ");
424 vfprintf (stderr
, string
, ap
);
425 fprintf (stderr
, ": %s\n", my_strerror (e
));
428 collect_exit (FATAL_EXIT_CODE
);
434 fatal
VPROTO((const char * string
, ...))
436 #ifndef ANSI_PROTOTYPES
441 VA_START (ap
, string
);
443 #ifndef ANSI_PROTOTYPES
444 string
= va_arg (ap
, const char *);
447 fprintf (stderr
, "collect2: ");
448 vfprintf (stderr
, string
, ap
);
449 fprintf (stderr
, "\n");
452 collect_exit (FATAL_EXIT_CODE
);
455 /* Write error message. */
458 error
VPROTO((const char * string
, ...))
460 #ifndef ANSI_PROTOTYPES
465 VA_START (ap
, string
);
467 #ifndef ANSI_PROTOTYPES
468 string
= va_arg (ap
, const char *);
471 fprintf (stderr
, "collect2: ");
472 vfprintf (stderr
, string
, ap
);
473 fprintf (stderr
, "\n");
477 /* In case obstack is linked in, and abort is defined to fancy_abort,
478 provide a default entry. */
483 fatal ("internal error");
491 if (c_file
!= 0 && c_file
[0])
492 maybe_unlink (c_file
);
494 if (o_file
!= 0 && o_file
[0])
495 maybe_unlink (o_file
);
497 if (ldout
!= 0 && ldout
[0])
498 maybe_unlink (ldout
);
500 #ifdef COLLECT_EXPORT_LIST
501 if (export_file
!= 0 && export_file
[0])
502 maybe_unlink (export_file
);
504 if (import_file
!= 0 && import_file
[0])
505 maybe_unlink (import_file
);
508 signal (signo
, SIG_DFL
);
509 kill (getpid (), signo
);
514 xcalloc (size1
, size2
)
517 PTR ptr
= (PTR
) calloc (size1
, size2
);
519 fatal ("out of memory");
527 PTR ptr
= (PTR
) malloc (size
);
529 fatal ("out of memory");
538 register PTR value
= (PTR
) realloc (ptr
, size
);
540 fatal ("virtual memory exhausted");
548 return access (name
, R_OK
) == 0;
551 /* Make a copy of a string INPUT with size SIZE. */
557 register size_t len
= strlen (input
) + 1;
558 register char *output
= xmalloc (len
);
559 memcpy (output
, input
, len
);
563 /* Parse a reasonable subset of shell quoting syntax. */
580 obstack_1grow (&temporary_obstack
, c
);
581 else if (! inside
&& c
== ' ')
583 else if (! inside
&& c
== '\\')
588 obstack_1grow (&temporary_obstack
, c
);
591 obstack_1grow (&temporary_obstack
, '\0');
593 return obstack_finish (&temporary_obstack
);
600 FILE *stream
= fopen (name
, "r");
601 int no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
608 while (c
= getc (stream
),
609 c
!= EOF
&& (ISALNUM (c
) || c
== '_' || c
== '$' || c
== '.'))
610 obstack_1grow (&temporary_obstack
, c
);
611 if (obstack_object_size (&temporary_obstack
) > 0)
613 char *word
, *p
, *result
;
614 obstack_1grow (&temporary_obstack
, '\0');
615 word
= obstack_finish (&temporary_obstack
);
618 ++word
, putc ('.', stderr
);
620 if (*p
== '_' && prepends_underscore
)
626 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
);
631 fputs (result
, stderr
);
633 diff
= strlen (word
) - strlen (result
);
635 --diff
, putc (' ', stderr
);
636 while (diff
< 0 && c
== ' ')
637 ++diff
, c
= getc (stream
);
642 fputs (word
, stderr
);
645 obstack_free (&temporary_obstack
, temporary_firstobj
);
654 /* Decide whether the given symbol is:
655 a constructor (1), a destructor (2), or neither (0). */
661 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
663 register struct names
*p
;
665 register char *orig_s
= s
;
667 static struct names special
[] = {
668 #ifdef NO_DOLLAR_IN_LABEL
669 #ifdef NO_DOT_IN_LABEL
670 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
671 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
672 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
674 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
675 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
676 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
679 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
680 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
681 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
683 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
684 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
685 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
686 cfront has its own linker procedure to collect them;
687 if collect2 gets them too, they get collected twice
688 when the cfront procedure is run and the compiler used
689 for linking happens to be GCC. */
690 { "sti__", sizeof ("sti__")-1, 1, 1 },
691 { "std__", sizeof ("std__")-1, 2, 1 },
692 #endif /* CFRONT_LOSSAGE */
696 while ((ch
= *s
) == '_')
702 for (p
= &special
[0]; p
->len
> 0; p
++)
705 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
706 && strncmp(s
, p
->name
, p
->len
) == 0)
714 /* Routine to add variables to the environment. */
722 #ifndef VMS /* nor about VMS */
724 extern char **environ
;
725 char **old_environ
= environ
;
732 while ((ch
= *p
++) != '\0' && ch
!= '=')
738 /* Search for replacing an existing environment variable, and
739 count the number of total environment variables. */
740 for (envp
= old_environ
; *envp
; envp
++)
743 if (!strncmp (str
, *envp
, name_len
))
750 /* Add a new environment variable */
751 environ
= (char **) xmalloc (sizeof (char *) * (num_envs
+2));
753 bcopy ((char *) old_environ
, (char *) (environ
+ 1),
754 sizeof (char *) * (num_envs
+1));
760 #endif /* HAVE_PUTENV */
762 /* By default, colon separates directories in a path. */
763 #ifndef PATH_SEPARATOR
764 #define PATH_SEPARATOR ':'
767 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
768 and one from the PATH variable. */
770 static struct path_prefix cpath
, path
;
773 /* This is the name of the target machine. We use it to form the name
774 of the files to execute. */
776 static char *target_machine
= TARGET_MACHINE
;
779 /* Search for NAME using prefix list PPREFIX. We only look for executable
782 Return 0 if not found, otherwise return its name, allocated with malloc. */
785 find_a_file (pprefix
, name
)
786 struct path_prefix
*pprefix
;
790 struct prefix_list
*pl
;
791 int len
= pprefix
->max_len
+ strlen (name
) + 1;
794 fprintf (stderr
, "Looking for '%s'\n", name
);
796 #ifdef EXECUTABLE_SUFFIX
797 len
+= strlen (EXECUTABLE_SUFFIX
);
800 temp
= xmalloc (len
);
802 /* Determine the filename to execute (special case for absolute paths). */
806 || (DIR_SEPARATOR
== '\\' && name
[1] == ':'
807 && (name
[2] == DIR_SEPARATOR
|| name
[2] == '/'))
811 if (access (name
, X_OK
) == 0)
816 fprintf (stderr
, " - found: absolute path\n");
822 fprintf (stderr
, " - failed to locate using absolute path\n");
825 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
827 strcpy (temp
, pl
->prefix
);
830 if (access (temp
, X_OK
) == 0)
833 #ifdef EXECUTABLE_SUFFIX
834 /* Some systems have a suffix for executable files.
835 So try appending that. */
836 strcat (temp
, EXECUTABLE_SUFFIX
);
838 if (access (temp
, X_OK
) == 0)
843 if (debug
&& pprefix
->plist
== NULL
)
844 fprintf (stderr
, " - failed: no entries in prefix list\n");
850 /* Add an entry for PREFIX to prefix list PPREFIX. */
853 add_prefix (pprefix
, prefix
)
854 struct path_prefix
*pprefix
;
857 struct prefix_list
*pl
, **prev
;
862 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
867 prev
= &pprefix
->plist
;
869 /* Keep track of the longest prefix */
871 len
= strlen (prefix
);
872 if (len
> pprefix
->max_len
)
873 pprefix
->max_len
= len
;
875 pl
= (struct prefix_list
*) xmalloc (sizeof (struct prefix_list
));
876 pl
->prefix
= xstrdup (prefix
);
881 pl
->next
= (struct prefix_list
*) 0;
885 /* Take the value of the environment variable ENV, break it into a path, and
886 add of the entries to PPREFIX. */
889 prefix_from_env (env
, pprefix
)
891 struct path_prefix
*pprefix
;
894 GET_ENV_PATH_LIST (p
, env
);
897 prefix_from_string (p
, pprefix
);
901 prefix_from_string (p
, pprefix
)
903 struct path_prefix
*pprefix
;
906 char *nstore
= (char *) xmalloc (strlen (p
) + 3);
909 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
914 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
916 strncpy (nstore
, startp
, endp
-startp
);
919 strcpy (nstore
, "./");
921 else if (endp
[-1] != '/')
923 nstore
[endp
-startp
] = '/';
924 nstore
[endp
-startp
+1] = 0;
927 nstore
[endp
-startp
] = 0;
930 fprintf (stderr
, " - add prefix: %s\n", nstore
);
932 add_prefix (pprefix
, nstore
);
935 endp
= startp
= endp
+ 1;
949 char *ld_suffix
= "ld";
950 char *full_ld_suffix
= ld_suffix
;
951 char *real_ld_suffix
= "real-ld";
952 char *collect_ld_suffix
= "collect-ld";
953 char *nm_suffix
= "nm";
954 char *full_nm_suffix
= nm_suffix
;
955 char *gnm_suffix
= "gnm";
956 char *full_gnm_suffix
= gnm_suffix
;
958 char *ldd_suffix
= LDD_SUFFIX
;
959 char *full_ldd_suffix
= ldd_suffix
;
961 char *strip_suffix
= "strip";
962 char *full_strip_suffix
= strip_suffix
;
963 char *gstrip_suffix
= "gstrip";
964 char *full_gstrip_suffix
= gstrip_suffix
;
967 #ifdef COLLECT_EXPORT_LIST
975 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+3);
976 char **ld1
= ld1_argv
;
977 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+6);
978 char **ld2
= ld2_argv
;
979 char **object_lst
= (char **) xcalloc (sizeof (char *), argc
);
980 char **object
= object_lst
;
982 int num_c_args
= argc
+9;
988 /* Parse command line early for instances of -debug. This allows
989 the debug flag to be set before functions like find_a_file()
994 for (i
= 1; argv
[i
] != NULL
; i
++)
995 if (! strcmp (argv
[i
], "-debug"))
1000 #ifndef DEFAULT_A_OUT_NAME
1001 output_file
= "a.out";
1003 output_file
= DEFAULT_A_OUT_NAME
;
1006 obstack_begin (&temporary_obstack
, 0);
1007 obstack_begin (&permanent_obstack
, 0);
1008 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
1010 current_demangling_style
= gnu_demangling
;
1011 p
= getenv ("COLLECT_GCC_OPTIONS");
1014 char *q
= extract_string (&p
);
1015 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1018 obstack_free (&temporary_obstack
, temporary_firstobj
);
1021 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
1024 fatal ("no arguments");
1027 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
1028 signal (SIGQUIT
, handler
);
1030 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
1031 signal (SIGINT
, handler
);
1033 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
1034 signal (SIGALRM
, handler
);
1037 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
1038 signal (SIGHUP
, handler
);
1040 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
1041 signal (SIGSEGV
, handler
);
1043 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
1044 signal (SIGBUS
, handler
);
1047 /* Extract COMPILER_PATH and PATH into our prefix list. */
1048 prefix_from_env ("COMPILER_PATH", &cpath
);
1049 prefix_from_env ("PATH", &path
);
1051 #ifdef CROSS_COMPILE
1052 /* If we look for a program in the compiler directories, we just use
1053 the short name, since these directories are already system-specific.
1054 But it we look for a program in the system directories, we need to
1055 qualify the program name with the target machine. */
1058 = xcalloc (strlen (ld_suffix
) + strlen (target_machine
) + 2, 1);
1059 strcpy (full_ld_suffix
, target_machine
);
1060 strcat (full_ld_suffix
, "-");
1061 strcat (full_ld_suffix
, ld_suffix
);
1065 = xcalloc (strlen (gld_suffix
) + strlen (target_machine
) + 2, 1);
1066 strcpy (full_gld_suffix
, target_machine
);
1067 strcat (full_gld_suffix
, "-");
1068 strcat (full_gld_suffix
, gld_suffix
);
1072 = xcalloc (strlen (nm_suffix
) + strlen (target_machine
) + 2, 1);
1073 strcpy (full_nm_suffix
, target_machine
);
1074 strcat (full_nm_suffix
, "-");
1075 strcat (full_nm_suffix
, nm_suffix
);
1078 = xcalloc (strlen (gnm_suffix
) + strlen (target_machine
) + 2, 1);
1079 strcpy (full_gnm_suffix
, target_machine
);
1080 strcat (full_gnm_suffix
, "-");
1081 strcat (full_gnm_suffix
, gnm_suffix
);
1085 = xcalloc (strlen (ldd_suffix
) + strlen (target_machine
) + 2, 1);
1086 strcpy (full_ldd_suffix
, target_machine
);
1087 strcat (full_ldd_suffix
, "-");
1088 strcat (full_ldd_suffix
, ldd_suffix
);
1092 = xcalloc (strlen (strip_suffix
) + strlen (target_machine
) + 2, 1);
1093 strcpy (full_strip_suffix
, target_machine
);
1094 strcat (full_strip_suffix
, "-");
1095 strcat (full_strip_suffix
, strip_suffix
);
1098 = xcalloc (strlen (gstrip_suffix
) + strlen (target_machine
) + 2, 1);
1099 strcpy (full_gstrip_suffix
, target_machine
);
1100 strcat (full_gstrip_suffix
, "-");
1101 strcat (full_gstrip_suffix
, gstrip_suffix
);
1102 #endif /* CROSS_COMPILE */
1104 /* Try to discover a valid linker/nm/strip to use. */
1106 /* Maybe we know the right file to use (if not cross). */
1108 #ifdef DEFAULT_LINKER
1109 if (access (DEFAULT_LINKER
, X_OK
) == 0)
1110 ld_file_name
= DEFAULT_LINKER
;
1111 if (ld_file_name
== 0)
1113 #ifdef REAL_LD_FILE_NAME
1114 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
1115 if (ld_file_name
== 0)
1117 /* Search the (target-specific) compiler dirs for ld'. */
1118 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
1119 /* Likewise for `collect-ld'. */
1120 if (ld_file_name
== 0)
1121 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
1122 /* Search the compiler directories for `ld'. We have protection against
1123 recursive calls in find_a_file. */
1124 if (ld_file_name
== 0)
1125 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
1126 /* Search the ordinary system bin directories
1127 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1128 if (ld_file_name
== 0)
1129 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
1131 #ifdef REAL_NM_FILE_NAME
1132 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
1133 if (nm_file_name
== 0)
1135 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
1136 if (nm_file_name
== 0)
1137 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
1138 if (nm_file_name
== 0)
1139 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
1140 if (nm_file_name
== 0)
1141 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
1144 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
1145 if (ldd_file_name
== 0)
1146 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
1149 #ifdef REAL_STRIP_FILE_NAME
1150 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
1151 if (strip_file_name
== 0)
1153 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
1154 if (strip_file_name
== 0)
1155 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
1156 if (strip_file_name
== 0)
1157 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1158 if (strip_file_name
== 0)
1159 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1161 /* Determine the full path name of the C compiler to use. */
1162 c_file_name
= getenv ("COLLECT_GCC");
1163 if (c_file_name
== 0)
1165 #ifdef CROSS_COMPILE
1166 c_file_name
= xcalloc (sizeof ("gcc-") + strlen (target_machine
) + 1, 1);
1167 strcpy (c_file_name
, target_machine
);
1168 strcat (c_file_name
, "-gcc");
1170 c_file_name
= "gcc";
1174 p
= find_a_file (&cpath
, c_file_name
);
1176 /* Here it should be safe to use the system search path since we should have
1177 already qualified the name of the compiler when it is needed. */
1179 p
= find_a_file (&path
, c_file_name
);
1184 *ld1
++ = *ld2
++ = ld_file_name
;
1186 /* Make temp file names. */
1187 c_file
= make_temp_file (".c");
1188 o_file
= make_temp_file (".o");
1189 #ifdef COLLECT_EXPORT_LIST
1190 export_file
= make_temp_file (".x");
1191 import_file
= make_temp_file (".p");
1193 ldout
= make_temp_file (".ld");
1194 *c_ptr
++ = c_file_name
;
1201 #ifdef COLLECT_EXPORT_LIST
1202 /* Generate a list of directories from LIBPATH. */
1203 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1204 /* Add to this list also two standard directories where
1205 AIX loader always searches for libraries. */
1206 add_prefix (&libpath_lib_dirs
, "/lib");
1207 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1210 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1212 AIX support needs to know if -shared has been specified before
1213 parsing commandline arguments. */
1215 p
= getenv ("COLLECT_GCC_OPTIONS");
1218 char *q
= extract_string (&p
);
1219 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1220 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1221 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1222 *c_ptr
++ = obstack_copy0 (&permanent_obstack
, q
, strlen (q
));
1223 if (strncmp (q
, "-shared", sizeof ("-shared") - 1) == 0)
1226 obstack_free (&temporary_obstack
, temporary_firstobj
);
1227 *c_ptr
++ = "-fno-exceptions";
1229 /* !!! When GCC calls collect2,
1230 it does not know whether it is calling collect2 or ld.
1231 So collect2 cannot meaningfully understand any options
1232 except those ld understands.
1233 If you propose to make GCC pass some other option,
1234 just imagine what will happen if ld is really ld!!! */
1236 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1237 /* After the first file, put in the c++ rt0. */
1240 while ((arg
= *++argv
) != (char *) 0)
1242 *ld1
++ = *ld2
++ = arg
;
1248 #ifdef COLLECT_EXPORT_LIST
1249 /* We want to disable automatic exports on AIX when user
1250 explicitly puts an export list in command line */
1252 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1254 else if (arg
[2] == '6' && arg
[3] == '4')
1260 if (!strcmp (arg
, "-debug"))
1262 /* Already parsed. */
1271 /* place o_file BEFORE this argument! */
1277 #ifdef COLLECT_EXPORT_LIST
1279 /* Resolving full library name. */
1280 char *s
= resolve_lib_name (arg
+2);
1282 /* If we will use an import list for this library,
1283 we should exclude it from ld args. */
1284 if (use_import_list (s
))
1290 /* Saving a full library name. */
1291 add_to_list (&libs
, s
);
1296 #ifdef COLLECT_EXPORT_LIST
1297 /* Saving directories where to search for libraries. */
1299 add_prefix (&cmdline_lib_dirs
, arg
+2);
1305 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1307 output_file
= &arg
[2];
1316 if (arg
[2] == '\0' && do_collecting
)
1318 /* We must strip after the nm run, otherwise C++ linking
1319 will not work. Thus we strip in the second ld run, or
1320 else with strip if there is no second ld run. */
1332 else if ((p
= rindex (arg
, '.')) != (char *) 0
1333 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1334 || strcmp (p
, ".so") == 0))
1343 /* place o_file BEFORE this argument! */
1351 #ifdef COLLECT_EXPORT_LIST
1352 /* libraries can be specified directly, i.e. without -l flag. */
1355 /* If we will use an import list for this library,
1356 we should exclude it from ld args. */
1357 if (use_import_list (arg
))
1363 /* Saving a full library name. */
1364 add_to_list (&libs
, arg
);
1370 #ifdef COLLECT_EXPORT_LIST
1371 /* This is added only for debugging purposes. */
1374 fprintf (stderr
, "List of libraries:\n");
1375 dump_list (stderr
, "\t", libs
.first
);
1378 /* The AIX linker will discard static constructors in object files if
1379 nothing else in the file is referenced, so look at them first. */
1381 char **export_object_lst
= object_lst
;
1382 while (export_object_lst
< object
)
1383 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1386 struct id
*list
= libs
.first
;
1387 for (; list
; list
= list
->next
)
1388 scan_prog_file (list
->name
, PASS_FIRST
);
1391 char *buf1
= alloca (strlen (export_file
) + 5);
1392 char *buf2
= alloca (strlen (import_file
) + 5);
1393 sprintf (buf1
, "-bE:%s", export_file
);
1394 sprintf (buf2
, "-bI:%s", import_file
);
1399 exportf
= fopen (export_file
, "w");
1400 if (exportf
== (FILE *) 0)
1401 fatal_perror ("%s", export_file
);
1402 write_export_file (exportf
);
1403 if (fclose (exportf
))
1404 fatal_perror ("closing %s", export_file
);
1405 importf
= fopen (import_file
, "w");
1406 if (importf
== (FILE *) 0)
1407 fatal_perror ("%s", import_file
);
1408 write_import_file (importf
);
1409 if (fclose (importf
))
1410 fatal_perror ("closing %s", import_file
);
1415 *object
= *c_ptr
= *ld1
= (char *) 0;
1419 fprintf (stderr
, "collect2 version %s", version_string
);
1420 #ifdef TARGET_VERSION
1423 fprintf (stderr
, "\n");
1429 fprintf (stderr
, "ld_file_name = %s\n",
1430 (ld_file_name
? ld_file_name
: "not found"));
1431 fprintf (stderr
, "c_file_name = %s\n",
1432 (c_file_name
? c_file_name
: "not found"));
1433 fprintf (stderr
, "nm_file_name = %s\n",
1434 (nm_file_name
? nm_file_name
: "not found"));
1436 fprintf (stderr
, "ldd_file_name = %s\n",
1437 (ldd_file_name
? ldd_file_name
: "not found"));
1439 fprintf (stderr
, "strip_file_name = %s\n",
1440 (strip_file_name
? strip_file_name
: "not found"));
1441 fprintf (stderr
, "c_file = %s\n",
1442 (c_file
? c_file
: "not found"));
1443 fprintf (stderr
, "o_file = %s\n",
1444 (o_file
? o_file
: "not found"));
1446 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1448 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1450 ptr
= getenv ("COLLECT_GCC");
1452 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1454 ptr
= getenv ("COMPILER_PATH");
1456 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1458 ptr
= getenv ("LIBRARY_PATH");
1460 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
1462 fprintf (stderr
, "\n");
1465 /* Load the program, searching all libraries and attempting to provide
1466 undefined symbols from repository information. */
1468 /* On AIX we do this later. */
1469 #ifndef COLLECT_EXPORT_LIST
1470 do_tlink (ld1_argv
, object_lst
);
1473 /* If -r or they will be run via some other method, do not build the
1474 constructor or destructor list, just return now. */
1476 #ifndef COLLECT_EXPORT_LIST
1481 #ifdef COLLECT_EXPORT_LIST
1482 /* But make sure we delete the export file we may have created. */
1483 if (export_file
!= 0 && export_file
[0])
1484 maybe_unlink (export_file
);
1485 if (import_file
!= 0 && import_file
[0])
1486 maybe_unlink (import_file
);
1488 maybe_unlink (c_file
);
1489 maybe_unlink (o_file
);
1493 /* Examine the namelist with nm and search it for static constructors
1494 and destructors to call.
1495 Write the constructor and destructor tables to a .s file and reload. */
1497 /* On AIX we already done scanning for global constructors/destructors. */
1498 #ifndef COLLECT_EXPORT_LIST
1499 scan_prog_file (output_file
, PASS_FIRST
);
1502 #ifdef SCAN_LIBRARIES
1503 scan_libraries (output_file
);
1508 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
1509 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
1512 if (constructors
.number
== 0 && destructors
.number
== 0
1513 && frame_tables
.number
== 0
1514 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1515 /* If we will be running these functions ourselves, we want to emit
1516 stubs into the shared library so that we do not have to relink
1517 dependent programs when we add static objects. */
1522 #ifdef COLLECT_EXPORT_LIST
1523 /* Doing tlink without additional code generation */
1524 do_tlink (ld1_argv
, object_lst
);
1526 /* Strip now if it was requested on the command line. */
1529 char **strip_argv
= (char **) xcalloc (sizeof (char *), 3);
1530 strip_argv
[0] = strip_file_name
;
1531 strip_argv
[1] = output_file
;
1532 strip_argv
[2] = (char *) 0;
1533 fork_execute ("strip", strip_argv
);
1536 #ifdef COLLECT_EXPORT_LIST
1537 maybe_unlink (export_file
);
1538 maybe_unlink (import_file
);
1540 maybe_unlink (c_file
);
1541 maybe_unlink (o_file
);
1545 /* Sort ctor and dtor lists by priority. */
1546 sort_ids (&constructors
);
1547 sort_ids (&destructors
);
1549 maybe_unlink(output_file
);
1550 outf
= fopen (c_file
, "w");
1551 if (outf
== (FILE *) 0)
1552 fatal_perror ("%s", c_file
);
1554 write_c_file (outf
, c_file
);
1557 fatal_perror ("closing %s", c_file
);
1559 /* Tell the linker that we have initializer and finalizer functions. */
1560 #ifdef LD_INIT_SWITCH
1561 *ld2
++ = LD_INIT_SWITCH
;
1563 *ld2
++ = LD_FINI_SWITCH
;
1568 #ifdef COLLECT_EXPORT_LIST
1571 add_to_list (&exports
, initname
);
1572 add_to_list (&exports
, fininame
);
1573 add_to_list (&exports
, "_GLOBAL__DI");
1574 add_to_list (&exports
, "_GLOBAL__DD");
1575 exportf
= fopen (export_file
, "w");
1576 if (exportf
== (FILE *) 0)
1577 fatal_perror ("%s", export_file
);
1578 write_export_file (exportf
);
1579 if (fclose (exportf
))
1580 fatal_perror ("closing %s", export_file
);
1586 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1587 output_file
, c_file
);
1588 write_c_file (stderr
, "stderr");
1589 fprintf (stderr
, "========== end of c_file\n\n");
1590 #ifdef COLLECT_EXPORT_LIST
1591 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1592 write_export_file (stderr
);
1593 fprintf (stderr
, "========== end of export_file\n\n");
1597 /* Assemble the constructor and destructor tables.
1598 Link the tables in with the rest of the program. */
1600 fork_execute ("gcc", c_argv
);
1601 #ifdef COLLECT_EXPORT_LIST
1602 /* On AIX we must call tlink because of possible templates resolution */
1603 do_tlink (ld2_argv
, object_lst
);
1605 /* Otherwise, simply call ld because tlink is already done */
1606 fork_execute ("ld", ld2_argv
);
1608 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1609 constructors/destructors in shared libraries. */
1610 scan_prog_file (output_file
, PASS_SECOND
);
1613 maybe_unlink (c_file
);
1614 maybe_unlink (o_file
);
1616 #ifdef COLLECT_EXPORT_LIST
1617 maybe_unlink (export_file
);
1618 maybe_unlink (import_file
);
1625 /* Wait for a process to finish, and exit if a non-zero status is found. */
1636 if (WIFSIGNALED (status
))
1638 int sig
= WTERMSIG (status
);
1639 error ("%s terminated with signal %d [%s]%s",
1643 (status
& 0200) ? ", core dumped" : "");
1645 collect_exit (FATAL_EXIT_CODE
);
1648 if (WIFEXITED (status
))
1649 return WEXITSTATUS (status
);
1658 int ret
= collect_wait (prog
);
1661 error ("%s returned %d exit status", prog
, ret
);
1667 /* Fork and execute a program, and wait for the reply. */
1670 collect_execute (prog
, argv
, redir
)
1683 fprintf (stderr
, "%s", argv
[0]);
1685 fprintf (stderr
, "[cannot find %s]", prog
);
1687 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1688 fprintf (stderr
, " %s", str
);
1690 fprintf (stderr
, "\n");
1696 /* If we cannot find a program we need, complain error. Do this here
1697 since we might not end up needing something that we could not find. */
1700 fatal ("cannot find `%s'", prog
);
1705 fatal_perror (VFORK_STRING
);
1707 if (pid
== 0) /* child context */
1712 if (freopen (redir
, "a", stdout
) == NULL
)
1713 fatal_perror ("redirecting stdout: %s", redir
);
1714 if (freopen (redir
, "a", stderr
) == NULL
)
1715 fatal_perror ("redirecting stderr: %s", redir
);
1718 execvp (argv
[0], argv
);
1719 fatal_perror ("executing %s", prog
);
1722 pid
= _spawnvp (_P_NOWAIT
, argv
[0], argv
);
1724 fatal ("spawnvp failed");
1729 fork_execute (prog
, argv
)
1733 collect_execute (prog
, argv
, NULL
);
1737 /* Unlink a file unless we are debugging. */
1746 fprintf (stderr
, "[Leaving %s]\n", file
);
1750 static long sequence_number
= 0;
1752 /* Add a name to a linked list. */
1755 add_to_list (head_ptr
, name
)
1756 struct head
*head_ptr
;
1760 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1762 strcpy (newid
->name
, name
);
1764 if (head_ptr
->first
)
1765 head_ptr
->last
->next
= newid
;
1767 head_ptr
->first
= newid
;
1769 /* Check for duplicate symbols. */
1770 for (p
= head_ptr
->first
;
1771 strcmp (name
, p
->name
) != 0;
1776 head_ptr
->last
->next
= 0;
1781 newid
->sequence
= ++sequence_number
;
1782 head_ptr
->last
= newid
;
1786 /* Grab the init priority number from an init function name that
1787 looks like "_GLOBAL_.I.12345.foo". */
1790 extract_init_priority (name
)
1795 while (name
[pos
] == '_')
1797 pos
+= 10; /* strlen ("GLOBAL__X_") */
1799 /* Extract init_p number from ctor/dtor name. */
1800 pri
= atoi (name
+ pos
);
1801 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1804 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1805 ctors will be run from right to left, dtors from left to right. */
1809 struct head
*head_ptr
;
1811 /* id holds the current element to insert. id_next holds the next
1812 element to insert. id_ptr iterates through the already sorted elements
1813 looking for the place to insert id. */
1814 struct id
*id
, *id_next
, **id_ptr
;
1816 id
= head_ptr
->first
;
1818 /* We don't have any sorted elements yet. */
1819 head_ptr
->first
= NULL
;
1821 for (; id
; id
= id_next
)
1824 id
->sequence
= extract_init_priority (id
->name
);
1826 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1828 /* If the sequence numbers are the same, we put the id from the
1829 file later on the command line later in the list. */
1830 || id
->sequence
> (*id_ptr
)->sequence
1831 /* Hack: do lexical compare, too.
1832 || (id->sequence == (*id_ptr)->sequence
1833 && strcmp (id->name, (*id_ptr)->name) > 0) */
1842 /* Now set the sequence numbers properly so write_c_file works. */
1843 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1844 id
->sequence
= ++sequence_number
;
1847 /* Write: `prefix', the names on list LIST, `suffix'. */
1850 write_list (stream
, prefix
, list
)
1857 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1862 #ifdef COLLECT_EXPORT_LIST
1863 /* This function is really used only on AIX, but may be useful. */
1865 is_in_list (prefix
, list
)
1871 if (!strcmp (prefix
, list
->name
)) return 1;
1878 /* Added for debugging purpose. */
1879 #ifdef COLLECT_EXPORT_LIST
1881 dump_list (stream
, prefix
, list
)
1888 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1896 dump_prefix_list (stream
, prefix
, list
)
1899 struct prefix_list
*list
;
1903 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1910 write_list_with_asm (stream
, prefix
, list
)
1917 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1918 prefix
, list
->sequence
, list
->name
);
1923 /* Write out the constructor and destructor tables statically (for a shared
1924 object), along with the functions to execute them. */
1927 write_c_file_stat (stream
, name
)
1931 char *prefix
, *p
, *q
;
1932 int frames
= (frame_tables
.number
> 0);
1934 /* Figure out name of output_file, stripping off .so version. */
1935 p
= rindex (output_file
, '/');
1937 p
= (char *) output_file
;
1951 if (strncmp (q
, ".so", 3) == 0)
1960 /* q points to null at end of the string (or . of the .so version) */
1961 prefix
= xmalloc (q
- p
+ 1);
1962 strncpy (prefix
, p
, q
- p
);
1964 for (q
= prefix
; *q
; q
++)
1965 if (!ISALNUM ((unsigned char)*q
))
1968 fprintf (stderr
, "\nwrite_c_file - output name is %s, prefix is %s\n",
1969 output_file
, prefix
);
1971 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1972 initname
= xmalloc (strlen (prefix
) + sizeof (INIT_NAME_FORMAT
) - 2);
1973 sprintf (initname
, INIT_NAME_FORMAT
, prefix
);
1975 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1976 fininame
= xmalloc (strlen (prefix
) + sizeof (FINI_NAME_FORMAT
) - 2);
1977 sprintf (fininame
, FINI_NAME_FORMAT
, prefix
);
1981 /* Write the tables as C code */
1983 fprintf (stream
, "static int count;\n");
1984 fprintf (stream
, "typedef void entry_pt();\n");
1985 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1989 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1991 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1992 write_list (stream
, "\t\t&", frame_tables
.first
);
1993 fprintf (stream
, "\t0\n};\n");
1995 /* This must match what's in frame.h. */
1996 fprintf (stream
, "struct object {\n");
1997 fprintf (stream
, " void *pc_begin;\n");
1998 fprintf (stream
, " void *pc_end;\n");
1999 fprintf (stream
, " void *fde_begin;\n");
2000 fprintf (stream
, " void *fde_array;\n");
2001 fprintf (stream
, " __SIZE_TYPE__ count;\n");
2002 fprintf (stream
, " struct object *next;\n");
2003 fprintf (stream
, "};\n");
2005 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2006 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2008 fprintf (stream
, "static void reg_frame () {\n");
2009 fprintf (stream
, "\tstatic struct object ob;\n");
2010 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2011 fprintf (stream
, "\t}\n");
2013 fprintf (stream
, "static void dereg_frame () {\n");
2014 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2015 fprintf (stream
, "\t}\n");
2018 fprintf (stream
, "void %s() {\n", initname
);
2019 if (constructors
.number
> 0 || frames
)
2021 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
2022 write_list (stream
, "\t\t", constructors
.first
);
2024 fprintf (stream
, "\treg_frame,\n");
2025 fprintf (stream
, "\t};\n");
2026 fprintf (stream
, "\tentry_pt **p;\n");
2027 fprintf (stream
, "\tif (count++ != 0) return;\n");
2028 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
2029 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
2032 fprintf (stream
, "\t++count;\n");
2033 fprintf (stream
, "}\n");
2034 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2035 fprintf (stream
, "void %s() {\n", fininame
);
2036 if (destructors
.number
> 0 || frames
)
2038 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
2039 write_list (stream
, "\t\t", destructors
.first
);
2041 fprintf (stream
, "\tdereg_frame,\n");
2042 fprintf (stream
, "\t};\n");
2043 fprintf (stream
, "\tentry_pt **p;\n");
2044 fprintf (stream
, "\tif (--count != 0) return;\n");
2045 fprintf (stream
, "\tp = dtors;\n");
2046 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
2047 destructors
.number
+ frames
);
2049 fprintf (stream
, "}\n");
2053 fprintf (stream
, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname
);
2054 fprintf (stream
, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame
);
2058 /* Write the constructor/destructor tables. */
2060 #ifndef LD_INIT_SWITCH
2062 write_c_file_glob (stream
, name
)
2066 /* Write the tables as C code */
2068 int frames
= (frame_tables
.number
> 0);
2070 fprintf (stream
, "typedef void entry_pt();\n\n");
2072 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
2076 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
2078 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
2079 write_list (stream
, "\t\t&", frame_tables
.first
);
2080 fprintf (stream
, "\t0\n};\n");
2082 /* This must match what's in frame.h. */
2083 fprintf (stream
, "struct object {\n");
2084 fprintf (stream
, " void *pc_begin;\n");
2085 fprintf (stream
, " void *pc_end;\n");
2086 fprintf (stream
, " void *fde_begin;\n");
2087 fprintf (stream
, " void *fde_array;\n");
2088 fprintf (stream
, " __SIZE_TYPE__ count;\n");
2089 fprintf (stream
, " struct object *next;\n");
2090 fprintf (stream
, "};\n");
2092 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2093 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2095 fprintf (stream
, "static void reg_frame () {\n");
2096 fprintf (stream
, "\tstatic struct object ob;\n");
2097 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2098 fprintf (stream
, "\t}\n");
2100 fprintf (stream
, "static void dereg_frame () {\n");
2101 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2102 fprintf (stream
, "\t}\n");
2105 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2106 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2107 write_list (stream
, "\t", constructors
.first
);
2109 fprintf (stream
, "\treg_frame,\n");
2110 fprintf (stream
, "\t0\n};\n\n");
2112 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2114 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2115 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2116 write_list (stream
, "\t", destructors
.first
);
2118 fprintf (stream
, "\tdereg_frame,\n");
2119 fprintf (stream
, "\t0\n};\n\n");
2121 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2122 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2124 #endif /* ! LD_INIT_SWITCH */
2127 write_c_file (stream
, name
)
2131 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2132 #ifndef LD_INIT_SWITCH
2134 write_c_file_glob (stream
, name
);
2137 write_c_file_stat (stream
, name
);
2138 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
2141 #ifdef COLLECT_EXPORT_LIST
2143 write_export_file (stream
)
2146 struct id
*list
= exports
.first
;
2147 for (; list
; list
= list
->next
)
2148 fprintf (stream
, "%s\n", list
->name
);
2152 write_import_file (stream
)
2155 struct id
*list
= imports
.first
;
2156 fprintf (stream
, "%s\n", "#! .");
2157 for (; list
; list
= list
->next
)
2158 fprintf (stream
, "%s\n", list
->name
);
2162 #ifdef OBJECT_FORMAT_NONE
2164 /* Generic version to scan the name list of the loaded program for
2165 the symbols g++ uses for static constructors and destructors.
2167 The constructor table begins at __CTOR_LIST__ and contains a count
2168 of the number of pointers (or -1 if the constructors are built in a
2169 separate section by the linker), followed by the pointers to the
2170 constructor functions, terminated with a null pointer. The
2171 destructor table has the same format, and begins at __DTOR_LIST__. */
2174 scan_prog_file (prog_name
, which_pass
)
2176 enum pass which_pass
;
2178 void (*int_handler
) ();
2179 void (*quit_handler
) ();
2187 if (which_pass
== PASS_SECOND
)
2190 /* If we do not have an `nm', complain. */
2191 if (nm_file_name
== 0)
2192 fatal ("cannot find `nm'");
2194 nm_argv
[argc
++] = nm_file_name
;
2195 if (NM_FLAGS
[0] != '\0')
2196 nm_argv
[argc
++] = NM_FLAGS
;
2198 nm_argv
[argc
++] = prog_name
;
2199 nm_argv
[argc
++] = (char *) 0;
2201 if (pipe (pipe_fd
) < 0)
2202 fatal_perror ("pipe");
2204 inf
= fdopen (pipe_fd
[0], "r");
2205 if (inf
== (FILE *) 0)
2206 fatal_perror ("fdopen");
2208 /* Trace if needed. */
2214 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2215 fprintf (stderr
, " %s", str
);
2217 fprintf (stderr
, "\n");
2223 /* Spawn child nm on pipe */
2226 fatal_perror (VFORK_STRING
);
2228 if (pid
== 0) /* child context */
2231 if (dup2 (pipe_fd
[1], 1) < 0)
2232 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
2234 if (close (pipe_fd
[0]) < 0)
2235 fatal_perror ("close (%d)", pipe_fd
[0]);
2237 if (close (pipe_fd
[1]) < 0)
2238 fatal_perror ("close (%d)", pipe_fd
[1]);
2240 execv (nm_file_name
, nm_argv
);
2241 fatal_perror ("executing %s", nm_file_name
);
2244 /* Parent context from here on. */
2245 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
2247 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
2250 if (close (pipe_fd
[1]) < 0)
2251 fatal_perror ("close (%d)", pipe_fd
[1]);
2254 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2256 /* Read each line of nm output. */
2257 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2262 /* If it contains a constructor or destructor name, add the name
2263 to the appropriate list. */
2265 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2266 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2273 /* Find the end of the symbol name.
2274 Do not include `|', because Encore nm can tack that on the end. */
2275 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2281 switch (is_ctor_dtor (name
))
2284 if (which_pass
!= PASS_LIB
)
2285 add_to_list (&constructors
, name
);
2289 if (which_pass
!= PASS_LIB
)
2290 add_to_list (&destructors
, name
);
2294 if (which_pass
!= PASS_LIB
)
2295 fatal ("init function found in object %s", prog_name
);
2296 #ifndef LD_INIT_SWITCH
2297 add_to_list (&constructors
, name
);
2302 if (which_pass
!= PASS_LIB
)
2303 fatal ("fini function found in object %s", prog_name
);
2304 #ifndef LD_FINI_SWITCH
2305 add_to_list (&destructors
, name
);
2310 if (which_pass
!= PASS_LIB
)
2311 add_to_list (&frame_tables
, name
);
2313 default: /* not a constructor or destructor */
2318 fprintf (stderr
, "\t%s\n", buf
);
2322 fprintf (stderr
, "\n");
2324 if (fclose (inf
) != 0)
2325 fatal_perror ("fclose of pipe");
2327 do_wait (nm_file_name
);
2329 signal (SIGINT
, int_handler
);
2331 signal (SIGQUIT
, quit_handler
);
2335 #if SUNOS4_SHARED_LIBRARIES
2337 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2338 that the output file depends upon and their initialization/finalization
2339 routines, if any. */
2344 #include <sys/mman.h>
2345 #include <sys/param.h>
2347 #include <sys/dir.h>
2349 /* pointers to the object file */
2350 unsigned object
; /* address of memory mapped file */
2351 unsigned objsize
; /* size of memory mapped to file */
2352 char * code
; /* pointer to code segment */
2353 char * data
; /* pointer to data segment */
2354 struct nlist
*symtab
; /* pointer to symbol table */
2355 struct link_dynamic
*ld
;
2356 struct link_dynamic_2
*ld_2
;
2357 struct head libraries
;
2359 /* Map the file indicated by NAME into memory and store its address. */
2367 if ((fp
= open (name
, O_RDONLY
)) == -1)
2368 fatal ("unable to open file '%s'", name
);
2369 if (fstat (fp
, &s
) == -1)
2370 fatal ("unable to stat file '%s'", name
);
2372 objsize
= s
.st_size
;
2373 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2376 fatal ("unable to mmap file '%s'", name
);
2381 /* Helpers for locatelib. */
2383 static char *libname
;
2389 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2392 /* If one file has an additional numeric extension past LIBNAME, then put
2393 that one first in the sort. If both files have additional numeric
2394 extensions, then put the one with the higher number first in the sort.
2396 We must verify that the extension is numeric, because Sun saves the
2397 original versions of patched libraries with a .FCS extension. Files with
2398 invalid extensions must go last in the sort, so that they will not be used. */
2402 struct direct
**d1
, **d2
;
2404 int i1
, i2
= strlen (libname
);
2405 char *e1
= (*d1
)->d_name
+ i2
;
2406 char *e2
= (*d2
)->d_name
+ i2
;
2408 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2409 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2413 i1
= strtol (e1
, &e1
, 10);
2414 i2
= strtol (e2
, &e2
, 10);
2421 /* It has a valid numeric extension, prefer this one. */
2422 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2424 /* It has a invalid numeric extension, must prefer the other one. */
2430 /* It has a valid numeric extension, prefer this one. */
2431 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2433 /* It has a invalid numeric extension, must prefer the other one. */
2441 /* Given the name NAME of a dynamic dependency, find its pathname and add
2442 it to the list of libraries. */
2450 char buf
[MAXPATHLEN
];
2458 /* counting elements in array, need 1 extra for null */
2460 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2464 for (; *ld_rules
!= 0; ld_rules
++)
2465 if (*ld_rules
== ':')
2467 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2468 ldr
= (char *) malloc (strlen (ld_rules
) + 1);
2469 strcpy (ldr
, ld_rules
);
2471 p
= getenv ("LD_LIBRARY_PATH");
2476 for (q
= p
; *q
!= 0; q
++)
2479 q
= (char *) malloc (strlen (p
) + 1);
2482 l
= (char **) malloc ((cnt
+ 3) * sizeof (char *));
2487 for (; *ldr
!= 0; ldr
++)
2497 for (; *q
!= 0; q
++)
2504 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2507 *pp
++ = "/usr/local/lib";
2511 for (pp
= l
; *pp
!= 0 ; pp
++)
2513 struct direct
**namelist
;
2515 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2517 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2518 add_to_list (&libraries
, buf
);
2520 fprintf (stderr
, "%s\n", buf
);
2527 fprintf (stderr
, "not found\n");
2529 fatal ("dynamic dependency %s not found", name
);
2533 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2534 that it depends upon and any constructors or destructors they contain. */
2537 scan_libraries (prog_name
)
2540 struct exec
*header
;
2542 struct link_object
*lo
;
2543 char buff
[MAXPATHLEN
];
2546 mapfile (prog_name
);
2547 header
= (struct exec
*)object
;
2548 if (N_BADMAG (*header
))
2549 fatal ("bad magic number in file '%s'", prog_name
);
2550 if (header
->a_dynamic
== 0)
2553 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2554 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2555 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2557 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2560 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2566 ld
= (struct link_dynamic
*) data
;
2571 fprintf (stderr
, "dynamic dependencies.\n");
2573 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2574 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2575 lo
= (struct link_object
*) lo
->lo_next
)
2578 lo
= (struct link_object
*) ((long) lo
+ code
);
2579 name
= (char *) (code
+ lo
->lo_name
);
2583 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2584 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2590 fprintf (stderr
, "\t%s\n", name
);
2591 add_to_list (&libraries
, name
);
2596 fprintf (stderr
, "\n");
2598 /* now iterate through the library list adding their symbols to
2600 for (list
= libraries
.first
; list
; list
= list
->next
)
2601 scan_prog_file (list
->name
, PASS_LIB
);
2604 #else /* SUNOS4_SHARED_LIBRARIES */
2607 /* Use the List Dynamic Dependencies program to find shared libraries that
2608 the output file depends upon and their initialization/finalization
2609 routines, if any. */
2612 scan_libraries (prog_name
)
2615 static struct head libraries
; /* list of shared libraries found */
2617 void (*int_handler
) ();
2618 void (*quit_handler
) ();
2626 /* If we do not have an `ldd', complain. */
2627 if (ldd_file_name
== 0)
2629 error ("cannot find `ldd'");
2633 ldd_argv
[argc
++] = ldd_file_name
;
2634 ldd_argv
[argc
++] = prog_name
;
2635 ldd_argv
[argc
++] = (char *) 0;
2637 if (pipe (pipe_fd
) < 0)
2638 fatal_perror ("pipe");
2640 inf
= fdopen (pipe_fd
[0], "r");
2641 if (inf
== (FILE *) 0)
2642 fatal_perror ("fdopen");
2644 /* Trace if needed. */
2650 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2651 fprintf (stderr
, " %s", str
);
2653 fprintf (stderr
, "\n");
2659 /* Spawn child ldd on pipe */
2662 fatal_perror (VFORK_STRING
);
2664 if (pid
== 0) /* child context */
2667 if (dup2 (pipe_fd
[1], 1) < 0)
2668 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
2670 if (close (pipe_fd
[0]) < 0)
2671 fatal_perror ("close (%d)", pipe_fd
[0]);
2673 if (close (pipe_fd
[1]) < 0)
2674 fatal_perror ("close (%d)", pipe_fd
[1]);
2676 execv (ldd_file_name
, ldd_argv
);
2677 fatal_perror ("executing %s", ldd_file_name
);
2680 /* Parent context from here on. */
2681 int_handler
= (void (*) ()) signal (SIGINT
, SIG_IGN
);
2683 quit_handler
= (void (*) ()) signal (SIGQUIT
, SIG_IGN
);
2686 if (close (pipe_fd
[1]) < 0)
2687 fatal_perror ("close (%d)", pipe_fd
[1]);
2690 fprintf (stderr
, "\nldd output with constructors/destructors.\n");
2692 /* Read each line of ldd output. */
2693 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2696 char *name
, *end
, *p
= buf
;
2698 /* Extract names of libraries and add to list. */
2699 PARSE_LDD_OUTPUT (p
);
2704 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2705 fatal ("dynamic dependency %s not found", buf
);
2707 /* Find the end of the symbol name. */
2709 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2714 if (access (name
, R_OK
) == 0)
2715 add_to_list (&libraries
, name
);
2717 fatal ("unable to open dynamic dependency '%s'", buf
);
2720 fprintf (stderr
, "\t%s\n", buf
);
2723 fprintf (stderr
, "\n");
2725 if (fclose (inf
) != 0)
2726 fatal_perror ("fclose of pipe");
2728 do_wait (ldd_file_name
);
2730 signal (SIGINT
, int_handler
);
2732 signal (SIGQUIT
, quit_handler
);
2735 /* now iterate through the library list adding their symbols to
2737 for (list
= libraries
.first
; list
; list
= list
->next
)
2738 scan_prog_file (list
->name
, PASS_LIB
);
2741 #endif /* LDD_SUFFIX */
2742 #endif /* SUNOS4_SHARED_LIBRARIES */
2744 #endif /* OBJECT_FORMAT_NONE */
2748 * COFF specific stuff.
2751 #ifdef OBJECT_FORMAT_COFF
2753 #if defined(EXTENDED_COFF)
2754 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2755 # define GCC_SYMENT SYMR
2756 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2757 # define GCC_SYMINC(X) (1)
2758 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2759 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2761 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2762 # define GCC_SYMENT SYMENT
2763 # define GCC_OK_SYMBOL(X) \
2764 (((X).n_sclass == C_EXT) && \
2765 ((X).n_scnum > N_UNDEF) && \
2766 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2767 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2768 # define GCC_UNDEF_SYMBOL(X) \
2769 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2770 # define GCC_SYMINC(X) ((X).n_numaux+1)
2771 # define GCC_SYMZERO(X) 0
2772 # define GCC_CHECK_HDR(X) \
2773 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2774 || (HEADER (X).f_magic == 0757 && aix64_flag))
2777 extern char *ldgetname ();
2779 /* COFF version to scan the name list of the loaded program for
2780 the symbols g++ uses for static constructors and destructors.
2782 The constructor table begins at __CTOR_LIST__ and contains a count
2783 of the number of pointers (or -1 if the constructors are built in a
2784 separate section by the linker), followed by the pointers to the
2785 constructor functions, terminated with a null pointer. The
2786 destructor table has the same format, and begins at __DTOR_LIST__. */
2789 scan_prog_file (prog_name
, which_pass
)
2791 enum pass which_pass
;
2793 LDFILE
*ldptr
= NULL
;
2794 int sym_index
, sym_count
;
2796 #ifdef COLLECT_EXPORT_LIST
2797 /* Should we generate an import list for given prog_name? */
2798 int import_flag
= (which_pass
== PASS_OBJ
? 0 : use_import_list (prog_name
));
2801 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2804 #ifdef COLLECT_EXPORT_LIST
2805 /* We do not need scanning for some standard C libraries. */
2806 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2809 /* On AIX we have a loop, because there is not much difference
2810 between an object and an archive. This trick allows us to
2811 eliminate scan_libraries() function. */
2815 if ((ldptr
= ldopen (prog_name
, ldptr
)) != NULL
)
2817 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2818 fatal ("%s: not a COFF file", prog_name
);
2820 if (GCC_CHECK_HDR (ldptr
))
2822 sym_count
= GCC_SYMBOLS (ldptr
);
2823 sym_index
= GCC_SYMZERO (ldptr
);
2825 #ifdef COLLECT_EXPORT_LIST
2826 /* Is current archive member a shared object? */
2827 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2830 while (sym_index
< sym_count
)
2834 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2836 sym_index
+= GCC_SYMINC (symbol
);
2838 if (GCC_OK_SYMBOL (symbol
))
2842 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2843 continue; /* should never happen */
2845 #ifdef XCOFF_DEBUGGING_INFO
2846 /* All AIX function names have a duplicate entry
2847 beginning with a dot. */
2852 switch (is_ctor_dtor (name
))
2855 if (! is_shared
) add_to_list (&constructors
, name
);
2856 #ifdef COLLECT_EXPORT_LIST
2857 if (which_pass
== PASS_OBJ
)
2858 add_to_list (&exports
, name
);
2859 /* If this symbol was undefined and we are building
2860 an import list, we should add a symbol to this
2864 && is_in_list (name
, undefined
.first
))
2865 add_to_list (&imports
, name
);
2870 if (! is_shared
) add_to_list (&destructors
, name
);
2871 #ifdef COLLECT_EXPORT_LIST
2872 if (which_pass
== PASS_OBJ
)
2873 add_to_list (&exports
, name
);
2874 /* If this symbol was undefined and we are building
2875 an import list, we should add a symbol to this
2879 && is_in_list (name
, undefined
.first
))
2880 add_to_list (&imports
, name
);
2884 #ifdef COLLECT_EXPORT_LIST
2887 add_to_list (&constructors
, name
);
2892 add_to_list (&destructors
, name
);
2896 default: /* not a constructor or destructor */
2897 #ifdef COLLECT_EXPORT_LIST
2898 /* If we are building a shared object on AIX we need
2899 to explicitly export all global symbols or add
2900 them to import list. */
2903 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2904 add_to_list (&exports
, name
);
2905 else if (! is_shared
&& which_pass
== PASS_FIRST
2907 && is_in_list(name
, undefined
.first
))
2908 add_to_list (&imports
, name
);
2914 #if !defined(EXTENDED_COFF)
2916 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2917 symbol
.n_scnum
, symbol
.n_sclass
,
2918 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2923 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2924 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2927 #ifdef COLLECT_EXPORT_LIST
2928 /* If we are building a shared object we should collect
2929 information about undefined symbols for later
2930 import list generation. */
2931 else if (shared_obj
&& GCC_UNDEF_SYMBOL (symbol
))
2935 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2936 continue; /* should never happen */
2938 /* All AIX function names have a duplicate entry
2939 beginning with a dot. */
2942 add_to_list (&undefined
, name
);
2947 #ifdef COLLECT_EXPORT_LIST
2950 /* If archive contains both 32-bit and 64-bit objects,
2951 we want to skip objects in other mode so mismatch normal. */
2953 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2954 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2960 fatal ("%s: cannot open as COFF file", prog_name
);
2962 #ifdef COLLECT_EXPORT_LIST
2963 /* On AIX loop continues while there are more members in archive. */
2965 while (ldclose (ldptr
) == FAILURE
);
2967 /* Otherwise we simply close ldptr. */
2968 (void) ldclose(ldptr
);
2973 #ifdef COLLECT_EXPORT_LIST
2975 /* This new function is used to decide whether we should
2976 generate import list for an object or to use it directly. */
2978 use_import_list (prog_name
)
2983 /* If we do not build a shared object then import list should not be used. */
2984 if (! shared_obj
) return 0;
2986 /* Currently we check only for libgcc, but this can be changed in future. */
2987 p
= strstr (prog_name
, "libgcc.a");
2988 if (p
!= 0 && (strlen (p
) == sizeof ("libgcc.a") - 1))
2993 /* Given a library name without "lib" prefix, this function
2994 returns a full library name including a path. */
2996 resolve_lib_name (name
)
3002 for (i
= 0; libpaths
[i
]; i
++)
3003 if (libpaths
[i
]->max_len
> l
)
3004 l
= libpaths
[i
]->max_len
;
3006 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
3008 for (i
= 0; libpaths
[i
]; i
++)
3010 struct prefix_list
*list
= libpaths
[i
]->plist
;
3011 for (; list
; list
= list
->next
)
3013 for (j
= 0; libexts
[j
]; j
++)
3015 /* The following lines are needed because path_prefix list
3016 may contain directories both with trailing '/' and
3019 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
3021 sprintf (lib_buf
, "%s%slib%s.%s",
3022 list
->prefix
, p
, name
, libexts
[j
]);
3023 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
3024 if (file_exists (lib_buf
))
3026 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
3033 fprintf (stderr
, "not found\n");
3035 fatal ("Library lib%s not found", name
);
3039 /* Array of standard AIX libraries which should not
3040 be scanned for ctors/dtors. */
3041 static char* aix_std_libs
[] = {
3046 "/usr/lib/libc_r.a",
3047 "/usr/lib/threads/libc.a",
3048 "/usr/ccs/lib/libc.a",
3049 "/usr/ccs/lib/libc_r.a",
3053 /* This function checks the filename and returns 1
3054 if this name matches the location of a standard AIX library. */
3056 ignore_library (name
)
3059 char **p
= &aix_std_libs
[0];
3060 while (*p
++ != NULL
)
3061 if (! strcmp (name
, *p
)) return 1;
3067 #endif /* OBJECT_FORMAT_COFF */
3071 * OSF/rose specific stuff.
3074 #ifdef OBJECT_FORMAT_ROSE
3076 /* Union of the various load commands */
3078 typedef union load_union
3080 ldc_header_t hdr
; /* common header */
3081 load_cmd_map_command_t map
; /* map indexing other load cmds */
3082 interpreter_command_t iprtr
; /* interpreter pathname */
3083 strings_command_t str
; /* load commands strings section */
3084 region_command_t region
; /* region load command */
3085 reloc_command_t reloc
; /* relocation section */
3086 package_command_t pkg
; /* package load command */
3087 symbols_command_t sym
; /* symbol sections */
3088 entry_command_t ent
; /* program start section */
3089 gen_info_command_t info
; /* object information */
3090 func_table_command_t func
; /* function constructors/destructors */
3093 /* Structure to point to load command and data section in memory. */
3095 typedef struct load_all
3097 load_union_t
*load
; /* load command */
3098 char *section
; /* pointer to section */
3101 /* Structure to contain information about a file mapped into memory. */
3105 char *start
; /* start of map */
3106 char *name
; /* filename */
3107 long size
; /* size of the file */
3108 long rounded_size
; /* size rounded to page boundary */
3109 int fd
; /* file descriptor */
3110 int rw
; /* != 0 if opened read/write */
3111 int use_mmap
; /* != 0 if mmap'ed */
3114 extern int decode_mach_o_hdr ();
3115 extern int encode_mach_o_hdr ();
3117 static void add_func_table
PROTO((mo_header_t
*, load_all_t
*,
3118 symbol_info_t
*, int));
3119 static void print_header
PROTO((mo_header_t
*));
3120 static void print_load_command
PROTO((load_union_t
*, size_t, int));
3121 static void bad_header
PROTO((int));
3122 static struct file_info
*read_file
PROTO((char *, int, int));
3123 static void end_file
PROTO((struct file_info
*));
3125 /* OSF/rose specific version to scan the name list of the loaded
3126 program for the symbols g++ uses for static constructors and
3129 The constructor table begins at __CTOR_LIST__ and contains a count
3130 of the number of pointers (or -1 if the constructors are built in a
3131 separate section by the linker), followed by the pointers to the
3132 constructor functions, terminated with a null pointer. The
3133 destructor table has the same format, and begins at __DTOR_LIST__. */
3136 scan_prog_file (prog_name
, which_pass
)
3138 enum pass which_pass
;
3142 load_all_t
*load_array
;
3143 load_all_t
*load_end
;
3144 load_all_t
*load_cmd
;
3145 int symbol_load_cmds
;
3151 struct file_info
*obj_file
;
3153 mo_lcid_t cmd_strings
= -1;
3154 symbol_info_t
*main_sym
= 0;
3155 int rw
= (which_pass
!= PASS_FIRST
);
3157 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
3159 fatal_perror ("cannot read %s", prog_name
);
3161 obj_file
= read_file (prog_name
, prog_fd
, rw
);
3162 obj
= obj_file
->start
;
3164 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
3165 if (status
!= MO_HDR_CONV_SUCCESS
)
3166 bad_header (status
);
3169 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3170 since the hardware will automatically swap bytes for us on loading little endian
3173 #ifndef CROSS_COMPILE
3174 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
3175 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
3176 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
3177 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
3178 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
3179 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
3180 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
3182 fatal ("incompatibilities between object file & expected values");
3187 print_header (&hdr
);
3189 offset
= hdr
.moh_first_cmd_off
;
3190 load_end
= load_array
3191 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
3193 /* Build array of load commands, calculating the offsets */
3194 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3196 load_union_t
*load_hdr
; /* load command header */
3198 load_cmd
= load_end
++;
3199 load_hdr
= (load_union_t
*) (obj
+ offset
);
3201 /* If modifying the program file, copy the header. */
3204 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
3205 bcopy ((char *)load_hdr
, (char *)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
3208 /* null out old command map, because we will rewrite at the end. */
3209 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3211 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
3212 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
3216 load_cmd
->load
= load_hdr
;
3217 if (load_hdr
->hdr
.ldci_section_off
> 0)
3218 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
3221 print_load_command (load_hdr
, offset
, i
);
3223 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
3226 /* If the last command is the load command map and is not undefined,
3227 decrement the count of load commands. */
3228 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
3231 hdr
.moh_n_load_cmds
--;
3234 /* Go through and process each symbol table section. */
3235 symbol_load_cmds
= 0;
3236 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
3238 load_union_t
*load_hdr
= load_cmd
->load
;
3240 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
3246 char *kind
= "unknown";
3248 switch (load_hdr
->sym
.symc_kind
)
3250 case SYMC_IMPORTS
: kind
= "imports"; break;
3251 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
3252 case SYMC_STABS
: kind
= "stabs"; break;
3255 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3256 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
3259 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
3262 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
3263 if (str_sect
== (char *) 0)
3264 fatal ("string section missing");
3266 if (load_cmd
->section
== (char *) 0)
3267 fatal ("section pointer missing");
3269 num_syms
= load_hdr
->sym
.symc_nentries
;
3270 for (i
= 0; i
< num_syms
; i
++)
3272 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
3273 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
3280 char *n
= name
+ strlen (name
) - strlen (NAME__MAIN
);
3282 if ((n
- name
) < 0 || strcmp (n
, NAME__MAIN
))
3292 switch (is_ctor_dtor (name
))
3295 add_to_list (&constructors
, name
);
3299 add_to_list (&destructors
, name
);
3302 default: /* not a constructor or destructor */
3308 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3309 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
3314 if (symbol_load_cmds
== 0)
3315 fatal ("no symbol table found");
3317 /* Update the program file now, rewrite header and load commands. At present,
3318 we assume that there is enough space after the last load command to insert
3319 one more. Since the first section written out is page aligned, and the
3320 number of load commands is small, this is ok for the present. */
3324 load_union_t
*load_map
;
3327 if (cmd_strings
== -1)
3328 fatal ("no cmd_strings found");
3330 /* Add __main to initializer list.
3331 If we are building a program instead of a shared library, do not
3332 do anything, since in the current version, you cannot do mallocs
3333 and such in the constructors. */
3335 if (main_sym
!= (symbol_info_t
*) 0
3336 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
3337 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
3340 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
3342 hdr
.moh_n_load_cmds
++;
3343 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
3345 /* Create new load command map. */
3347 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
3348 (int)hdr
.moh_n_load_cmds
, (long)size
);
3350 load_map
= (load_union_t
*) xcalloc (1, size
);
3351 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
3352 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
3353 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
3354 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
3355 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
3357 offset
= hdr
.moh_first_cmd_off
;
3358 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3360 load_map
->map
.lcm_map
[i
] = offset
;
3361 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
3362 hdr
.moh_load_map_cmd_off
= offset
;
3364 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
3367 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
3370 print_header (&hdr
);
3373 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
3374 if (status
!= MO_HDR_CONV_SUCCESS
)
3375 bad_header (status
);
3378 fprintf (stderr
, "writing load commands.\n\n");
3380 /* Write load commands */
3381 offset
= hdr
.moh_first_cmd_off
;
3382 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
3384 load_union_t
*load_hdr
= load_array
[i
].load
;
3385 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
3388 print_load_command (load_hdr
, offset
, i
);
3390 bcopy ((char *) load_hdr
, (char *) (obj
+ offset
), size
);
3395 end_file (obj_file
);
3397 if (close (prog_fd
))
3398 fatal_perror ("closing %s", prog_name
);
3401 fprintf (stderr
, "\n");
3405 /* Add a function table to the load commands to call a function
3406 on initiation or termination of the process. */
3409 add_func_table (hdr_p
, load_array
, sym
, type
)
3410 mo_header_t
*hdr_p
; /* pointer to global header */
3411 load_all_t
*load_array
; /* array of ptrs to load cmds */
3412 symbol_info_t
*sym
; /* pointer to symbol entry */
3413 int type
; /* fntc_type value */
3415 /* Add a new load command. */
3416 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
3417 int load_index
= num_cmds
- 1;
3418 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
3419 load_union_t
*ptr
= xcalloc (1, size
);
3420 load_all_t
*load_cmd
;
3423 /* Set the unresolved address bit in the header to force the loader to be
3424 used, since kernel exec does not call the initialization functions. */
3425 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
3427 load_cmd
= &load_array
[load_index
];
3428 load_cmd
->load
= ptr
;
3429 load_cmd
->section
= (char *) 0;
3431 /* Fill in func table load command. */
3432 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
3433 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
3434 ptr
->func
.ldc_header
.ldci_section_off
= 0;
3435 ptr
->func
.ldc_header
.ldci_section_len
= 0;
3436 ptr
->func
.fntc_type
= type
;
3437 ptr
->func
.fntc_nentries
= 1;
3439 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3440 /* Is the symbol already expressed as (region, offset)? */
3441 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
3443 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
3444 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
3447 /* If not, figure out which region it's in. */
3450 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
3453 for (i
= 0; i
< load_index
; i
++)
3455 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
3457 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
3459 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
3460 && addr
>= region_ptr
->regc_addr
.vm_addr
3461 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
3463 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
3464 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
3472 fatal ("could not convert 0x%l.8x into a region", addr
);
3477 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3478 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
3479 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
3480 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
3481 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
3486 /* Print the global header for an OSF/rose object. */
3489 print_header (hdr_ptr
)
3490 mo_header_t
*hdr_ptr
;
3492 fprintf (stderr
, "\nglobal header:\n");
3493 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
3494 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
3495 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
3496 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
3497 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
3498 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
3499 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
3500 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
3501 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
3502 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
3503 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
3504 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
3505 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
3506 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
3507 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
3509 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
3510 fprintf (stderr
, ", relocatable");
3512 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
3513 fprintf (stderr
, ", linkable");
3515 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
3516 fprintf (stderr
, ", execable");
3518 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
3519 fprintf (stderr
, ", executable");
3521 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
3522 fprintf (stderr
, ", unresolved");
3524 fprintf (stderr
, "\n\n");
3529 /* Print a short summary of a load command. */
3532 print_load_command (load_hdr
, offset
, number
)
3533 load_union_t
*load_hdr
;
3537 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
3538 char *type_str
= (char *) 0;
3542 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
3543 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
3544 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
3545 case LDC_STRINGS
: type_str
= "STRINGS"; break;
3546 case LDC_REGION
: type_str
= "REGION"; break;
3547 case LDC_RELOC
: type_str
= "RELOC"; break;
3548 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
3549 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
3550 case LDC_ENTRY
: type_str
= "ENTRY"; break;
3551 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
3552 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
3556 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3558 (long) load_hdr
->hdr
.ldci_cmd_size
,
3560 (long) load_hdr
->hdr
.ldci_section_off
,
3561 (long) load_hdr
->hdr
.ldci_section_len
);
3563 if (type_str
== (char *) 0)
3564 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
3566 else if (type
!= LDC_REGION
)
3567 fprintf (stderr
, ", ty: %s\n", type_str
);
3572 switch (load_hdr
->region
.regc_usage_type
)
3574 case REG_TEXT_T
: region
= ", .text"; break;
3575 case REG_DATA_T
: region
= ", .data"; break;
3576 case REG_BSS_T
: region
= ", .bss"; break;
3577 case REG_GLUE_T
: region
= ", .glue"; break;
3578 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3579 case REG_RDATA_T
: region
= ", .rdata"; break;
3580 case REG_SDATA_T
: region
= ", .sdata"; break;
3581 case REG_SBSS_T
: region
= ", .sbss"; break;
3585 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3587 (long) load_hdr
->region
.regc_vm_addr
,
3588 (long) load_hdr
->region
.regc_vm_size
,
3596 /* Fatal error when {en,de}code_mach_o_header fails. */
3602 char *msg
= (char *) 0;
3606 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
3607 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
3608 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
3609 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
3610 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
3611 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
3614 if (msg
== (char *) 0)
3615 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
3621 /* Read a file into a memory buffer. */
3623 static struct file_info
*
3624 read_file (name
, fd
, rw
)
3625 char *name
; /* filename */
3626 int fd
; /* file descriptor */
3627 int rw
; /* read/write */
3629 struct stat stat_pkt
;
3630 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
3632 static int page_size
;
3635 if (fstat (fd
, &stat_pkt
) < 0)
3636 fatal_perror ("fstat %s", name
);
3639 p
->size
= stat_pkt
.st_size
;
3640 p
->rounded_size
= stat_pkt
.st_size
;
3646 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
3649 page_size
= sysconf (_SC_PAGE_SIZE
);
3651 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
3652 p
->start
= mmap ((caddr_t
) 0,
3653 (rw
) ? p
->rounded_size
: p
->size
,
3654 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
3655 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
3659 if (p
->start
!= (char *) 0 && p
->start
!= (char *) -1)
3663 #endif /* USE_MMAP */
3668 fprintf (stderr
, "read %s\n", name
);
3671 p
->start
= xmalloc (p
->size
);
3672 if (lseek (fd
, 0L, SEEK_SET
) < 0)
3673 fatal_perror ("lseek to 0 on %s", name
);
3675 len
= read (fd
, p
->start
, p
->size
);
3677 fatal_perror ("read %s", name
);
3680 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
3686 /* Do anything necessary to write a file back from memory. */
3690 struct file_info
*ptr
; /* file information block */
3698 fprintf (stderr
, "msync %s\n", ptr
->name
);
3700 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
3701 fatal_perror ("msync %s", ptr
->name
);
3705 fprintf (stderr
, "munmap %s\n", ptr
->name
);
3707 if (munmap (ptr
->start
, ptr
->size
))
3708 fatal_perror ("munmap %s", ptr
->name
);
3711 #endif /* USE_MMAP */
3718 fprintf (stderr
, "write %s\n", ptr
->name
);
3720 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
3721 fatal_perror ("lseek to 0 on %s", ptr
->name
);
3723 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
3725 fatal_perror ("write %s", ptr
->name
);
3727 if (len
!= ptr
->size
)
3728 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
3737 #endif /* OBJECT_FORMAT_ROSE */