--with-gnu-ld uses different x- fiile under aix 4.1
[official-gcc.git] / gcc / collect2.c
blob2184e0e23983093d2e43f8c06a4bf8da9788c742
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)
13 any later version.
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. */
28 #include "config.h"
29 #include "system.h"
30 #include <signal.h>
32 #ifdef vfork /* Autoconf may define this to fork for us. */
33 # define VFORK_STRING "fork"
34 #else
35 # define VFORK_STRING "vfork"
36 #endif
37 #ifdef HAVE_VFORK_H
38 #include <vfork.h>
39 #endif
40 #ifdef VMS
41 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
42 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
43 #endif /* VMS */
45 #define COLLECT
47 #include "collect2.h"
48 #include "demangle.h"
49 #include "obstack.h"
50 #ifdef __CYGWIN__
51 #include <process.h>
52 #endif
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. */
66 #ifdef CROSS_COMPILE
67 #undef SUNOS4_SHARED_LIBRARIES
68 #undef OBJECT_FORMAT_COFF
69 #undef OBJECT_FORMAT_ROSE
70 #undef MD_EXEC_PREFIX
71 #undef REAL_LD_FILE_NAME
72 #undef REAL_NM_FILE_NAME
73 #undef REAL_STRIP_FILE_NAME
74 #endif
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
83 #endif
85 #ifdef OBJECT_FORMAT_COFF
87 #include <a.out.h>
88 #include <ar.h>
90 #ifdef UMAX
91 #include <sgs.h>
92 #endif
94 /* Many versions of ldfcn.h define these. */
95 #ifdef FREAD
96 #undef FREAD
97 #undef FWRITE
98 #endif
100 #include <ldfcn.h>
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. */
107 #ifndef MY_ISCOFF
108 #define MY_ISCOFF(X) ISCOFF (X)
109 #endif
111 #endif /* OBJECT_FORMAT_COFF */
113 #ifdef OBJECT_FORMAT_ROSE
115 #ifdef _OSF_SOURCE
116 #define USE_MMAP
117 #endif
119 #ifdef USE_MMAP
120 #include <sys/mman.h>
121 #endif
123 #include <unistd.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. */
134 #ifndef NM_FLAGS
135 #define NM_FLAGS "-n"
136 #endif
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. */
144 #ifndef NAME__MAIN
145 #define NAME__MAIN "__main"
146 #define SYMBOL__MAIN __main
147 #endif
149 /* This must match tree.h. */
150 #define DEFAULT_INIT_PRIORITY 65535
152 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
153 #define SCAN_LIBRARIES
154 #endif
156 #ifdef USE_COLLECT2
157 int do_collecting = 1;
158 #else
159 int do_collecting = 0;
160 #endif
162 /* Linked lists of constructor and destructor names. */
164 struct id
166 struct id *next;
167 int sequence;
168 char name[1];
171 struct head
173 struct id *first;
174 struct id *last;
175 int number;
178 /* Enumeration giving which pass this is for scanning the program file. */
180 enum pass {
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 */
195 #endif
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. */
206 #endif
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 */
210 #ifdef LDD_SUFFIX
211 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
212 #endif
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 */
223 #endif
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)
237 #endif
239 /* Structure to hold all the directories in which to search for files to
240 execute. */
242 struct prefix_list
244 char *prefix; /* String to prepend to the path. */
245 struct prefix_list *next; /* Next in linked list. */
248 struct path_prefix
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 */
263 #endif
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 *));
287 #endif
288 #if 0
289 static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
290 #endif
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 *));
296 #endif
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 *));
304 #endif
306 #ifdef NO_DUP2
308 dup2 (oldfd, newfd)
309 int oldfd;
310 int newfd;
312 int fdtmp[256];
313 int fdx = 0;
314 int fd;
316 if (oldfd == newfd)
317 return oldfd;
318 close (newfd);
319 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
320 fdtmp[fdx++] = fd;
321 while (fdx > 0)
322 close (fdtmp[--fdx]);
324 return fd;
326 #endif
328 static char *
329 my_strerror (e)
330 int e;
333 #ifdef HAVE_STRERROR
334 return strerror (e);
336 #else
338 static char buffer[30];
339 if (!e)
340 return "";
342 if (e > 0 && e < sys_nerr)
343 return sys_errlist[e];
345 sprintf (buffer, "Unknown error %d", e);
346 return buffer;
347 #endif
350 static const char *
351 my_strsignal (s)
352 int s;
354 #ifdef HAVE_STRSIGNAL
355 return strsignal (s);
356 #else
357 if (s >= 0 && s < NSIG)
359 # ifdef NO_SYS_SIGLIST
360 static char buffer[30];
362 sprintf (buffer, "Unknown signal %d", s);
363 return buffer;
364 # else
365 return sys_siglist[s];
366 # endif
368 else
369 return NULL;
370 #endif /* HAVE_STRSIGNAL */
373 /* Delete tempfiles and exit function. */
375 void
376 collect_exit (status)
377 int 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);
391 #endif
393 if (ldout != 0 && ldout[0])
395 dump_file (ldout);
396 maybe_unlink (ldout);
399 if (status != 0 && output_file != 0 && output_file[0])
400 maybe_unlink (output_file);
402 exit (status);
406 /* Die when sys call fails. */
408 void
409 fatal_perror VPROTO((const char * string, ...))
411 #ifndef ANSI_PROTOTYPES
412 const char *string;
413 #endif
414 int e = errno;
415 va_list ap;
417 VA_START (ap, string);
419 #ifndef ANSI_PROTOTYPES
420 string = va_arg (ap, const char *);
421 #endif
423 fprintf (stderr, "collect2: ");
424 vfprintf (stderr, string, ap);
425 fprintf (stderr, ": %s\n", my_strerror (e));
426 va_end (ap);
428 collect_exit (FATAL_EXIT_CODE);
431 /* Just die. */
433 void
434 fatal VPROTO((const char * string, ...))
436 #ifndef ANSI_PROTOTYPES
437 const char *string;
438 #endif
439 va_list ap;
441 VA_START (ap, string);
443 #ifndef ANSI_PROTOTYPES
444 string = va_arg (ap, const char *);
445 #endif
447 fprintf (stderr, "collect2: ");
448 vfprintf (stderr, string, ap);
449 fprintf (stderr, "\n");
450 va_end (ap);
452 collect_exit (FATAL_EXIT_CODE);
455 /* Write error message. */
457 void
458 error VPROTO((const char * string, ...))
460 #ifndef ANSI_PROTOTYPES
461 const char * string;
462 #endif
463 va_list ap;
465 VA_START (ap, string);
467 #ifndef ANSI_PROTOTYPES
468 string = va_arg (ap, const char *);
469 #endif
471 fprintf (stderr, "collect2: ");
472 vfprintf (stderr, string, ap);
473 fprintf (stderr, "\n");
474 va_end(ap);
477 /* In case obstack is linked in, and abort is defined to fancy_abort,
478 provide a default entry. */
480 void
481 fancy_abort ()
483 fatal ("internal error");
487 static void
488 handler (signo)
489 int signo;
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);
506 #endif
508 signal (signo, SIG_DFL);
509 kill (getpid (), signo);
514 xcalloc (size1, size2)
515 size_t size1, size2;
517 PTR ptr = (PTR) calloc (size1, size2);
518 if (!ptr)
519 fatal ("out of memory");
520 return ptr;
524 xmalloc (size)
525 size_t size;
527 PTR ptr = (PTR) malloc (size);
528 if (!ptr)
529 fatal ("out of memory");
530 return ptr;
534 xrealloc (ptr, size)
535 PTR ptr;
536 size_t size;
538 register PTR value = (PTR) realloc (ptr, size);
539 if (value == 0)
540 fatal ("virtual memory exhausted");
541 return value;
545 file_exists (name)
546 char *name;
548 return access (name, R_OK) == 0;
551 /* Make a copy of a string INPUT with size SIZE. */
553 char *
554 xstrdup (input)
555 const char *input;
557 register size_t len = strlen (input) + 1;
558 register char *output = xmalloc (len);
559 memcpy (output, input, len);
560 return output;
563 /* Parse a reasonable subset of shell quoting syntax. */
565 static char *
566 extract_string (pp)
567 char **pp;
569 char *p = *pp;
570 int backquote = 0;
571 int inside = 0;
573 for (;;)
575 char c = *p;
576 if (c == '\0')
577 break;
578 ++p;
579 if (backquote)
580 obstack_1grow (&temporary_obstack, c);
581 else if (! inside && c == ' ')
582 break;
583 else if (! inside && c == '\\')
584 backquote = 1;
585 else if (c == '\'')
586 inside = !inside;
587 else
588 obstack_1grow (&temporary_obstack, c);
591 obstack_1grow (&temporary_obstack, '\0');
592 *pp = p;
593 return obstack_finish (&temporary_obstack);
596 void
597 dump_file (name)
598 char *name;
600 FILE *stream = fopen (name, "r");
601 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
603 if (stream == 0)
604 return;
605 while (1)
607 int c;
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);
617 if (*word == '.')
618 ++word, putc ('.', stderr);
619 p = word;
620 if (*p == '_' && prepends_underscore)
621 ++p;
623 if (no_demangle)
624 result = 0;
625 else
626 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
628 if (result)
630 int diff;
631 fputs (result, stderr);
633 diff = strlen (word) - strlen (result);
634 while (diff > 0)
635 --diff, putc (' ', stderr);
636 while (diff < 0 && c == ' ')
637 ++diff, c = getc (stream);
639 free (result);
641 else
642 fputs (word, stderr);
644 fflush (stderr);
645 obstack_free (&temporary_obstack, temporary_firstobj);
647 if (c == EOF)
648 break;
649 putc (c, stderr);
651 fclose (stream);
654 /* Decide whether the given symbol is:
655 a constructor (1), a destructor (2), or neither (0). */
657 static int
658 is_ctor_dtor (s)
659 char *s;
661 struct names { char *name; int len; int ret; int two_underscores; };
663 register struct names *p;
664 register int ch;
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 },
673 #else
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 },
677 #endif
678 #else
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 },
682 #endif
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 */
693 { NULL, 0, 0, 0 }
696 while ((ch = *s) == '_')
697 ++s;
699 if (s == orig_s)
700 return 0;
702 for (p = &special[0]; p->len > 0; p++)
704 if (ch == p->name[0]
705 && (!p->two_underscores || ((s - orig_s) >= 2))
706 && strncmp(s, p->name, p->len) == 0)
708 return p->ret;
711 return 0;
714 /* Routine to add variables to the environment. */
716 #ifndef HAVE_PUTENV
719 putenv (str)
720 char *str;
722 #ifndef VMS /* nor about VMS */
724 extern char **environ;
725 char **old_environ = environ;
726 char **envp;
727 int num_envs = 0;
728 int name_len = 1;
729 char *p = str;
730 int ch;
732 while ((ch = *p++) != '\0' && ch != '=')
733 name_len++;
735 if (!ch)
736 abort ();
738 /* Search for replacing an existing environment variable, and
739 count the number of total environment variables. */
740 for (envp = old_environ; *envp; envp++)
742 num_envs++;
743 if (!strncmp (str, *envp, name_len))
745 *envp = str;
746 return 0;
750 /* Add a new environment variable */
751 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
752 *environ = str;
753 bcopy ((char *) old_environ, (char *) (environ + 1),
754 sizeof (char *) * (num_envs+1));
756 return 0;
757 #endif /* VMS */
760 #endif /* HAVE_PUTENV */
762 /* By default, colon separates directories in a path. */
763 #ifndef PATH_SEPARATOR
764 #define PATH_SEPARATOR ':'
765 #endif
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;
772 #ifdef CROSS_COMPILE
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;
777 #endif
779 /* Search for NAME using prefix list PPREFIX. We only look for executable
780 files.
782 Return 0 if not found, otherwise return its name, allocated with malloc. */
784 static char *
785 find_a_file (pprefix, name)
786 struct path_prefix *pprefix;
787 char *name;
789 char *temp;
790 struct prefix_list *pl;
791 int len = pprefix->max_len + strlen (name) + 1;
793 if (debug)
794 fprintf (stderr, "Looking for '%s'\n", name);
796 #ifdef EXECUTABLE_SUFFIX
797 len += strlen (EXECUTABLE_SUFFIX);
798 #endif
800 temp = xmalloc (len);
802 /* Determine the filename to execute (special case for absolute paths). */
804 if (*name == '/'
805 #ifdef DIR_SEPARATOR
806 || (DIR_SEPARATOR == '\\' && name[1] == ':'
807 && (name[2] == DIR_SEPARATOR || name[2] == '/'))
808 #endif
811 if (access (name, X_OK) == 0)
813 strcpy (temp, name);
815 if (debug)
816 fprintf (stderr, " - found: absolute path\n");
818 return temp;
821 if (debug)
822 fprintf (stderr, " - failed to locate using absolute path\n");
824 else
825 for (pl = pprefix->plist; pl; pl = pl->next)
827 strcpy (temp, pl->prefix);
828 strcat (temp, name);
830 if (access (temp, X_OK) == 0)
831 return temp;
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)
839 return temp;
840 #endif
843 if (debug && pprefix->plist == NULL)
844 fprintf (stderr, " - failed: no entries in prefix list\n");
846 free (temp);
847 return 0;
850 /* Add an entry for PREFIX to prefix list PPREFIX. */
852 static void
853 add_prefix (pprefix, prefix)
854 struct path_prefix *pprefix;
855 char *prefix;
857 struct prefix_list *pl, **prev;
858 int len;
860 if (pprefix->plist)
862 for (pl = pprefix->plist; pl->next; pl = pl->next)
864 prev = &pl->next;
866 else
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);
878 if (*prev)
879 pl->next = *prev;
880 else
881 pl->next = (struct prefix_list *) 0;
882 *prev = pl;
885 /* Take the value of the environment variable ENV, break it into a path, and
886 add of the entries to PPREFIX. */
888 static void
889 prefix_from_env (env, pprefix)
890 char *env;
891 struct path_prefix *pprefix;
893 char *p;
894 GET_ENV_PATH_LIST (p, env);
896 if (p)
897 prefix_from_string (p, pprefix);
900 static void
901 prefix_from_string (p, pprefix)
902 char *p;
903 struct path_prefix *pprefix;
905 char *startp, *endp;
906 char *nstore = (char *) xmalloc (strlen (p) + 3);
908 if (debug)
909 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
911 startp = endp = p;
912 while (1)
914 if (*endp == PATH_SEPARATOR || *endp == 0)
916 strncpy (nstore, startp, endp-startp);
917 if (endp == startp)
919 strcpy (nstore, "./");
921 else if (endp[-1] != '/')
923 nstore[endp-startp] = '/';
924 nstore[endp-startp+1] = 0;
926 else
927 nstore[endp-startp] = 0;
929 if (debug)
930 fprintf (stderr, " - add prefix: %s\n", nstore);
932 add_prefix (pprefix, nstore);
933 if (*endp == 0)
934 break;
935 endp = startp = endp + 1;
937 else
938 endp++;
942 /* Main program. */
945 main (argc, argv)
946 int argc;
947 char *argv[];
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;
957 #ifdef LDD_SUFFIX
958 char *ldd_suffix = LDD_SUFFIX;
959 char *full_ldd_suffix = ldd_suffix;
960 #endif
961 char *strip_suffix = "strip";
962 char *full_strip_suffix = strip_suffix;
963 char *gstrip_suffix = "gstrip";
964 char *full_gstrip_suffix = gstrip_suffix;
965 char *arg;
966 FILE *outf;
967 #ifdef COLLECT_EXPORT_LIST
968 FILE *exportf;
969 FILE *importf;
970 #endif
971 char *ld_file_name;
972 char *p;
973 char **c_argv;
974 char **c_ptr;
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;
981 int first_file;
982 int num_c_args = argc+9;
984 #ifdef DEBUG
985 debug = 1;
986 #endif
988 /* Parse command line early for instances of -debug. This allows
989 the debug flag to be set before functions like find_a_file()
990 are called. */
992 int i;
994 for (i = 1; argv[i] != NULL; i ++)
995 if (! strcmp (argv[i], "-debug"))
996 debug = 1;
997 vflag = debug;
1000 #ifndef DEFAULT_A_OUT_NAME
1001 output_file = "a.out";
1002 #else
1003 output_file = DEFAULT_A_OUT_NAME;
1004 #endif
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");
1012 while (p && *p)
1014 char *q = extract_string (&p);
1015 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1016 num_c_args++;
1018 obstack_free (&temporary_obstack, temporary_firstobj);
1019 ++num_c_args;
1021 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1023 if (argc < 2)
1024 fatal ("no arguments");
1026 #ifdef SIGQUIT
1027 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1028 signal (SIGQUIT, handler);
1029 #endif
1030 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1031 signal (SIGINT, handler);
1032 #ifdef SIGALRM
1033 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1034 signal (SIGALRM, handler);
1035 #endif
1036 #ifdef SIGHUP
1037 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1038 signal (SIGHUP, handler);
1039 #endif
1040 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1041 signal (SIGSEGV, handler);
1042 #ifdef SIGBUS
1043 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1044 signal (SIGBUS, handler);
1045 #endif
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. */
1057 full_ld_suffix
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);
1063 #if 0
1064 full_gld_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);
1069 #endif
1071 full_nm_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);
1077 full_gnm_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);
1083 #ifdef LDD_SUFFIX
1084 full_ldd_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);
1089 #endif
1091 full_strip_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);
1097 full_gstrip_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). */
1107 ld_file_name = 0;
1108 #ifdef DEFAULT_LINKER
1109 if (access (DEFAULT_LINKER, X_OK) == 0)
1110 ld_file_name = DEFAULT_LINKER;
1111 if (ld_file_name == 0)
1112 #endif
1113 #ifdef REAL_LD_FILE_NAME
1114 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1115 if (ld_file_name == 0)
1116 #endif
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)
1134 #endif
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);
1143 #ifdef LDD_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);
1147 #endif
1149 #ifdef REAL_STRIP_FILE_NAME
1150 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1151 if (strip_file_name == 0)
1152 #endif
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");
1169 #else
1170 c_file_name = "gcc";
1171 #endif
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. */
1178 if (p == 0)
1179 p = find_a_file (&path, c_file_name);
1181 if (p)
1182 c_file_name = p;
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");
1192 #endif
1193 ldout = make_temp_file (".ld");
1194 *c_ptr++ = c_file_name;
1195 *c_ptr++ = "-x";
1196 *c_ptr++ = "c";
1197 *c_ptr++ = "-c";
1198 *c_ptr++ = "-o";
1199 *c_ptr++ = o_file;
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");
1208 #endif
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");
1216 while (p && *p)
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)
1224 shared_obj = 1;
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. */
1239 first_file = 1;
1240 while ((arg = *++argv) != (char *) 0)
1242 *ld1++ = *ld2++ = arg;
1244 if (arg[0] == '-')
1246 switch (arg[1])
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 */
1251 case 'b':
1252 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1253 export_flag = 1;
1254 else if (arg[2] == '6' && arg[3] == '4')
1255 aix64_flag = 1;
1256 break;
1257 #endif
1259 case 'd':
1260 if (!strcmp (arg, "-debug"))
1262 /* Already parsed. */
1263 ld1--;
1264 ld2--;
1266 break;
1268 case 'l':
1269 if (first_file)
1271 /* place o_file BEFORE this argument! */
1272 first_file = 0;
1273 ld2--;
1274 *ld2++ = o_file;
1275 *ld2++ = arg;
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))
1286 ld1--;
1287 ld2--;
1290 /* Saving a full library name. */
1291 add_to_list (&libs, s);
1293 #endif
1294 break;
1296 #ifdef COLLECT_EXPORT_LIST
1297 /* Saving directories where to search for libraries. */
1298 case 'L':
1299 add_prefix (&cmdline_lib_dirs, arg+2);
1300 break;
1301 #endif
1303 case 'o':
1304 if (arg[2] == '\0')
1305 output_file = *ld1++ = *ld2++ = *++argv;
1306 else
1307 output_file = &arg[2];
1308 break;
1310 case 'r':
1311 if (arg[2] == '\0')
1312 rflag = 1;
1313 break;
1315 case 's':
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. */
1321 strip_flag = 1;
1322 ld1--;
1324 break;
1326 case 'v':
1327 if (arg[2] == '\0')
1328 vflag = 1;
1329 break;
1332 else if ((p = rindex (arg, '.')) != (char *) 0
1333 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1334 || strcmp (p, ".so") == 0))
1336 if (first_file)
1338 first_file = 0;
1339 if (p[1] == 'o')
1340 *ld2++ = o_file;
1341 else
1343 /* place o_file BEFORE this argument! */
1344 ld2--;
1345 *ld2++ = o_file;
1346 *ld2++ = arg;
1349 if (p[1] == 'o')
1350 *object++ = arg;
1351 #ifdef COLLECT_EXPORT_LIST
1352 /* libraries can be specified directly, i.e. without -l flag. */
1353 else
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))
1359 ld1--;
1360 ld2--;
1363 /* Saving a full library name. */
1364 add_to_list (&libs, arg);
1366 #endif
1370 #ifdef COLLECT_EXPORT_LIST
1371 /* This is added only for debugging purposes. */
1372 if (debug)
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);
1395 *ld1++ = buf1;
1396 *ld2++ = buf1;
1397 *ld1++ = buf2;
1398 *ld2++ = buf2;
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);
1412 #endif
1414 *c_ptr++ = c_file;
1415 *object = *c_ptr = *ld1 = (char *) 0;
1417 if (vflag)
1419 fprintf (stderr, "collect2 version %s", version_string);
1420 #ifdef TARGET_VERSION
1421 TARGET_VERSION;
1422 #endif
1423 fprintf (stderr, "\n");
1426 if (debug)
1428 char *ptr;
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"));
1435 #ifdef LDD_SUFFIX
1436 fprintf (stderr, "ldd_file_name = %s\n",
1437 (ldd_file_name ? ldd_file_name : "not found"));
1438 #endif
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");
1447 if (ptr)
1448 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1450 ptr = getenv ("COLLECT_GCC");
1451 if (ptr)
1452 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1454 ptr = getenv ("COMPILER_PATH");
1455 if (ptr)
1456 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1458 ptr = getenv ("LIBRARY_PATH");
1459 if (ptr)
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);
1471 #endif
1473 /* If -r or they will be run via some other method, do not build the
1474 constructor or destructor list, just return now. */
1475 if (rflag
1476 #ifndef COLLECT_EXPORT_LIST
1477 || ! do_collecting
1478 #endif
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);
1487 #endif
1488 maybe_unlink (c_file);
1489 maybe_unlink (o_file);
1490 return 0;
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);
1500 #endif
1502 #ifdef SCAN_LIBRARIES
1503 scan_libraries (output_file);
1504 #endif
1506 if (debug)
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. */
1518 && ! shared_obj
1519 #endif
1522 #ifdef COLLECT_EXPORT_LIST
1523 /* Doing tlink without additional code generation */
1524 do_tlink (ld1_argv, object_lst);
1525 #endif
1526 /* Strip now if it was requested on the command line. */
1527 if (strip_flag)
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);
1539 #endif
1540 maybe_unlink (c_file);
1541 maybe_unlink (o_file);
1542 return 0;
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);
1556 if (fclose (outf))
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;
1562 *ld2++ = initname;
1563 *ld2++ = LD_FINI_SWITCH;
1564 *ld2++ = fininame;
1565 #endif
1566 *ld2 = (char*) 0;
1568 #ifdef COLLECT_EXPORT_LIST
1569 if (shared_obj)
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);
1582 #endif
1584 if (debug)
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");
1594 #endif
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);
1604 #else
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);
1611 #endif
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);
1619 #endif
1621 return 0;
1625 /* Wait for a process to finish, and exit if a non-zero status is found. */
1628 collect_wait (prog)
1629 char *prog;
1631 int status;
1633 wait (&status);
1634 if (status)
1636 if (WIFSIGNALED (status))
1638 int sig = WTERMSIG (status);
1639 error ("%s terminated with signal %d [%s]%s",
1640 prog,
1641 sig,
1642 my_strsignal(sig),
1643 (status & 0200) ? ", core dumped" : "");
1645 collect_exit (FATAL_EXIT_CODE);
1648 if (WIFEXITED (status))
1649 return WEXITSTATUS (status);
1651 return 0;
1654 static void
1655 do_wait (prog)
1656 char *prog;
1658 int ret = collect_wait (prog);
1659 if (ret != 0)
1661 error ("%s returned %d exit status", prog, ret);
1662 collect_exit (ret);
1667 /* Fork and execute a program, and wait for the reply. */
1669 void
1670 collect_execute (prog, argv, redir)
1671 char *prog;
1672 char **argv;
1673 char *redir;
1675 int pid;
1677 if (vflag || debug)
1679 char **p_argv;
1680 char *str;
1682 if (argv[0])
1683 fprintf (stderr, "%s", argv[0]);
1684 else
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");
1693 fflush (stdout);
1694 fflush (stderr);
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. */
1699 if (argv[0] == 0)
1700 fatal ("cannot find `%s'", prog);
1702 #ifndef __CYGWIN__
1703 pid = vfork ();
1704 if (pid == -1)
1705 fatal_perror (VFORK_STRING);
1707 if (pid == 0) /* child context */
1709 if (redir)
1711 unlink (redir);
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);
1721 #else
1722 pid = _spawnvp (_P_NOWAIT, argv[0], argv);
1723 if (pid == -1)
1724 fatal ("spawnvp failed");
1725 #endif
1728 static void
1729 fork_execute (prog, argv)
1730 char *prog;
1731 char **argv;
1733 collect_execute (prog, argv, NULL);
1734 do_wait (prog);
1737 /* Unlink a file unless we are debugging. */
1739 static void
1740 maybe_unlink (file)
1741 char *file;
1743 if (!debug)
1744 unlink (file);
1745 else
1746 fprintf (stderr, "[Leaving %s]\n", file);
1750 static long sequence_number = 0;
1752 /* Add a name to a linked list. */
1754 static void
1755 add_to_list (head_ptr, name)
1756 struct head *head_ptr;
1757 char *name;
1759 struct id *newid
1760 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1761 struct id *p;
1762 strcpy (newid->name, name);
1764 if (head_ptr->first)
1765 head_ptr->last->next = newid;
1766 else
1767 head_ptr->first = newid;
1769 /* Check for duplicate symbols. */
1770 for (p = head_ptr->first;
1771 strcmp (name, p->name) != 0;
1772 p = p->next)
1774 if (p != newid)
1776 head_ptr->last->next = 0;
1777 free (newid);
1778 return;
1781 newid->sequence = ++sequence_number;
1782 head_ptr->last = newid;
1783 head_ptr->number++;
1786 /* Grab the init priority number from an init function name that
1787 looks like "_GLOBAL_.I.12345.foo". */
1789 static int
1790 extract_init_priority (name)
1791 char *name;
1793 int pos = 0, pri;
1795 while (name[pos] == '_')
1796 ++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. */
1807 static void
1808 sort_ids (head_ptr)
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)
1823 id_next = id->next;
1824 id->sequence = extract_init_priority (id->name);
1826 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1827 if (*id_ptr == NULL
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) */
1836 id->next = *id_ptr;
1837 *id_ptr = id;
1838 break;
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'. */
1849 static void
1850 write_list (stream, prefix, list)
1851 FILE *stream;
1852 char *prefix;
1853 struct id *list;
1855 while (list)
1857 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1858 list = list->next;
1862 #ifdef COLLECT_EXPORT_LIST
1863 /* This function is really used only on AIX, but may be useful. */
1864 static int
1865 is_in_list (prefix, list)
1866 char *prefix;
1867 struct id *list;
1869 while (list)
1871 if (!strcmp (prefix, list->name)) return 1;
1872 list = list->next;
1874 return 0;
1876 #endif
1878 /* Added for debugging purpose. */
1879 #ifdef COLLECT_EXPORT_LIST
1880 static void
1881 dump_list (stream, prefix, list)
1882 FILE *stream;
1883 char *prefix;
1884 struct id *list;
1886 while (list)
1888 fprintf (stream, "%s%s,\n", prefix, list->name);
1889 list = list->next;
1892 #endif
1894 #if 0
1895 static void
1896 dump_prefix_list (stream, prefix, list)
1897 FILE *stream;
1898 char *prefix;
1899 struct prefix_list *list;
1901 while (list)
1903 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1904 list = list->next;
1907 #endif
1909 static void
1910 write_list_with_asm (stream, prefix, list)
1911 FILE *stream;
1912 char *prefix;
1913 struct id *list;
1915 while (list)
1917 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1918 prefix, list->sequence, list->name);
1919 list = list->next;
1923 /* Write out the constructor and destructor tables statically (for a shared
1924 object), along with the functions to execute them. */
1926 static void
1927 write_c_file_stat (stream, name)
1928 FILE *stream;
1929 char *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, '/');
1936 if (p == 0)
1937 p = (char *) output_file;
1938 else
1939 p++;
1940 q = p;
1941 while (q)
1943 q = index (q,'.');
1944 if (q == 0)
1946 q = p + strlen (p);
1947 break;
1949 else
1951 if (strncmp (q, ".so", 3) == 0)
1953 q += 3;
1954 break;
1956 else
1957 q++;
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);
1963 prefix[q - p] = 0;
1964 for (q = prefix; *q; q++)
1965 if (!ISALNUM ((unsigned char)*q))
1966 *q = '_';
1967 if (debug)
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);
1979 free (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);
1987 if (frames)
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);
2023 if (frames)
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");
2031 else
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);
2040 if (frames)
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");
2051 if (shared_obj)
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
2061 static void
2062 write_c_file_glob (stream, name)
2063 FILE *stream;
2064 char *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);
2074 if (frames)
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);
2108 if (frames)
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);
2117 if (frames)
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 */
2126 static void
2127 write_c_file (stream, name)
2128 FILE *stream;
2129 char *name;
2131 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2132 #ifndef LD_INIT_SWITCH
2133 if (! shared_obj)
2134 write_c_file_glob (stream, name);
2135 else
2136 #endif
2137 write_c_file_stat (stream, name);
2138 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2141 #ifdef COLLECT_EXPORT_LIST
2142 static void
2143 write_export_file (stream)
2144 FILE *stream;
2146 struct id *list = exports.first;
2147 for (; list; list = list->next)
2148 fprintf (stream, "%s\n", list->name);
2151 static void
2152 write_import_file (stream)
2153 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);
2160 #endif
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__. */
2173 static void
2174 scan_prog_file (prog_name, which_pass)
2175 char *prog_name;
2176 enum pass which_pass;
2178 void (*int_handler) ();
2179 void (*quit_handler) ();
2180 char *nm_argv[4];
2181 int pid;
2182 int argc = 0;
2183 int pipe_fd[2];
2184 char *p, buf[1024];
2185 FILE *inf;
2187 if (which_pass == PASS_SECOND)
2188 return;
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. */
2209 if (vflag)
2211 char **p_argv;
2212 char *str;
2214 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2215 fprintf (stderr, " %s", str);
2217 fprintf (stderr, "\n");
2220 fflush (stdout);
2221 fflush (stderr);
2223 /* Spawn child nm on pipe */
2224 pid = vfork ();
2225 if (pid == -1)
2226 fatal_perror (VFORK_STRING);
2228 if (pid == 0) /* child context */
2230 /* setup stdout */
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);
2246 #ifdef SIGQUIT
2247 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2248 #endif
2250 if (close (pipe_fd[1]) < 0)
2251 fatal_perror ("close (%d)", pipe_fd[1]);
2253 if (debug)
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)
2259 int ch, ch2;
2260 char *name, *end;
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] == ' ')
2267 break;
2269 if (ch != '_')
2270 continue;
2272 name = p;
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 != '|';
2276 end++)
2277 continue;
2280 *end = '\0';
2281 switch (is_ctor_dtor (name))
2283 case 1:
2284 if (which_pass != PASS_LIB)
2285 add_to_list (&constructors, name);
2286 break;
2288 case 2:
2289 if (which_pass != PASS_LIB)
2290 add_to_list (&destructors, name);
2291 break;
2293 case 3:
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);
2298 #endif
2299 break;
2301 case 4:
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);
2306 #endif
2307 break;
2309 case 5:
2310 if (which_pass != PASS_LIB)
2311 add_to_list (&frame_tables, name);
2313 default: /* not a constructor or destructor */
2314 continue;
2317 if (debug)
2318 fprintf (stderr, "\t%s\n", buf);
2321 if (debug)
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);
2330 #ifdef SIGQUIT
2331 signal (SIGQUIT, quit_handler);
2332 #endif
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. */
2341 #include <a.out.h>
2342 #include <fcntl.h>
2343 #include <link.h>
2344 #include <sys/mman.h>
2345 #include <sys/param.h>
2346 #include <unistd.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. */
2361 static void
2362 mapfile (name)
2363 char *name;
2365 int fp;
2366 struct stat s;
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,
2374 fp, 0);
2375 if (object == -1)
2376 fatal ("unable to mmap file '%s'", name);
2378 close (fp);
2381 /* Helpers for locatelib. */
2383 static char *libname;
2385 static int
2386 libselect (d)
2387 struct direct *d;
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. */
2400 static int
2401 libcompare (d1, d2)
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]))
2411 ++e1;
2412 ++e2;
2413 i1 = strtol (e1, &e1, 10);
2414 i2 = strtol (e2, &e2, 10);
2415 if (i1 != i2)
2416 return i1 - i2;
2419 if (*e1)
2421 /* It has a valid numeric extension, prefer this one. */
2422 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2423 return 1;
2424 /* It has a invalid numeric extension, must prefer the other one. */
2425 else
2426 return -1;
2428 else if (*e2)
2430 /* It has a valid numeric extension, prefer this one. */
2431 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2432 return -1;
2433 /* It has a invalid numeric extension, must prefer the other one. */
2434 else
2435 return 1;
2437 else
2438 return 0;
2441 /* Given the name NAME of a dynamic dependency, find its pathname and add
2442 it to the list of libraries. */
2444 static void
2445 locatelib (name)
2446 char *name;
2448 static char **l;
2449 static int cnt;
2450 char buf[MAXPATHLEN];
2451 char *p, *q;
2452 char **pp;
2454 if (l == 0)
2456 char *ld_rules;
2457 char *ldr = 0;
2458 /* counting elements in array, need 1 extra for null */
2459 cnt = 1;
2460 ld_rules = (char *) (ld_2->ld_rules + code);
2461 if (ld_rules)
2463 cnt++;
2464 for (; *ld_rules != 0; ld_rules++)
2465 if (*ld_rules == ':')
2466 cnt++;
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");
2472 q = 0;
2473 if (p)
2475 cnt++;
2476 for (q = p ; *q != 0; q++)
2477 if (*q == ':')
2478 cnt++;
2479 q = (char *) malloc (strlen (p) + 1);
2480 strcpy (q, p);
2482 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2483 pp = l;
2484 if (ldr)
2486 *pp++ = ldr;
2487 for (; *ldr != 0; ldr++)
2488 if (*ldr == ':')
2490 *ldr++ = 0;
2491 *pp++ = ldr;
2494 if (q)
2496 *pp++ = q;
2497 for (; *q != 0; q++)
2498 if (*q == ':')
2500 *q++ = 0;
2501 *pp++ = q;
2504 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2505 *pp++ = "/lib";
2506 *pp++ = "/usr/lib";
2507 *pp++ = "/usr/local/lib";
2508 *pp = 0;
2510 libname = name;
2511 for (pp = l; *pp != 0 ; pp++)
2513 struct direct **namelist;
2514 int entries;
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);
2519 if (debug)
2520 fprintf (stderr, "%s\n", buf);
2521 break;
2524 if (*pp == 0)
2526 if (debug)
2527 fprintf (stderr, "not found\n");
2528 else
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. */
2536 static void
2537 scan_libraries (prog_name)
2538 char *prog_name;
2540 struct exec *header;
2541 char *base;
2542 struct link_object *lo;
2543 char buff[MAXPATHLEN];
2544 struct id *list;
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)
2551 return;
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)
2559 /* shared object */
2560 ld = (struct link_dynamic *) (symtab->n_value + code);
2561 base = code;
2563 else
2565 /* executable */
2566 ld = (struct link_dynamic *) data;
2567 base = code-PAGSIZ;
2570 if (debug)
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)
2577 char *name;
2578 lo = (struct link_object *) ((long) lo + code);
2579 name = (char *) (code + lo->lo_name);
2580 if (lo->lo_library)
2582 if (debug)
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);
2585 locatelib (buff);
2587 else
2589 if (debug)
2590 fprintf (stderr, "\t%s\n", name);
2591 add_to_list (&libraries, name);
2595 if (debug)
2596 fprintf (stderr, "\n");
2598 /* now iterate through the library list adding their symbols to
2599 the list. */
2600 for (list = libraries.first; list; list = list->next)
2601 scan_prog_file (list->name, PASS_LIB);
2604 #else /* SUNOS4_SHARED_LIBRARIES */
2605 #ifdef LDD_SUFFIX
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. */
2611 static void
2612 scan_libraries (prog_name)
2613 char *prog_name;
2615 static struct head libraries; /* list of shared libraries found */
2616 struct id *list;
2617 void (*int_handler) ();
2618 void (*quit_handler) ();
2619 char *ldd_argv[4];
2620 int pid;
2621 int argc = 0;
2622 int pipe_fd[2];
2623 char buf[1024];
2624 FILE *inf;
2626 /* If we do not have an `ldd', complain. */
2627 if (ldd_file_name == 0)
2629 error ("cannot find `ldd'");
2630 return;
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. */
2645 if (vflag)
2647 char **p_argv;
2648 char *str;
2650 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2651 fprintf (stderr, " %s", str);
2653 fprintf (stderr, "\n");
2656 fflush (stdout);
2657 fflush (stderr);
2659 /* Spawn child ldd on pipe */
2660 pid = vfork ();
2661 if (pid == -1)
2662 fatal_perror (VFORK_STRING);
2664 if (pid == 0) /* child context */
2666 /* setup stdout */
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);
2682 #ifdef SIGQUIT
2683 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2684 #endif
2686 if (close (pipe_fd[1]) < 0)
2687 fatal_perror ("close (%d)", pipe_fd[1]);
2689 if (debug)
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)
2695 int ch, ch2;
2696 char *name, *end, *p = buf;
2698 /* Extract names of libraries and add to list. */
2699 PARSE_LDD_OUTPUT (p);
2700 if (p == 0)
2701 continue;
2703 name = 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. */
2708 for (end = p;
2709 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2710 end++)
2711 continue;
2712 *end = '\0';
2714 if (access (name, R_OK) == 0)
2715 add_to_list (&libraries, name);
2716 else
2717 fatal ("unable to open dynamic dependency '%s'", buf);
2719 if (debug)
2720 fprintf (stderr, "\t%s\n", buf);
2722 if (debug)
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);
2731 #ifdef SIGQUIT
2732 signal (SIGQUIT, quit_handler);
2733 #endif
2735 /* now iterate through the library list adding their symbols to
2736 the list. */
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)
2760 #else
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))
2775 #endif
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__. */
2788 static void
2789 scan_prog_file (prog_name, which_pass)
2790 char *prog_name;
2791 enum pass which_pass;
2793 LDFILE *ldptr = NULL;
2794 int sym_index, sym_count;
2795 int is_shared = 0;
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));
2799 #endif
2801 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2802 return;
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))
2807 return;
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. */
2814 #endif
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;
2828 #endif
2830 while (sym_index < sym_count)
2832 GCC_SYMENT symbol;
2834 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2835 break;
2836 sym_index += GCC_SYMINC (symbol);
2838 if (GCC_OK_SYMBOL (symbol))
2840 char *name;
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. */
2848 if (*name == '.')
2849 ++name;
2850 #endif
2852 switch (is_ctor_dtor (name))
2854 case 1:
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
2861 list. */
2862 else
2863 if (import_flag
2864 && is_in_list (name, undefined.first))
2865 add_to_list (&imports, name);
2866 #endif
2867 break;
2869 case 2:
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
2876 list. */
2877 else
2878 if (import_flag
2879 && is_in_list (name, undefined.first))
2880 add_to_list (&imports, name);
2881 #endif
2882 break;
2884 #ifdef COLLECT_EXPORT_LIST
2885 case 3:
2886 if (is_shared)
2887 add_to_list (&constructors, name);
2888 break;
2890 case 4:
2891 if (is_shared)
2892 add_to_list (&destructors, name);
2893 break;
2894 #endif
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. */
2901 if (shared_obj)
2903 if (which_pass == PASS_OBJ && (! export_flag))
2904 add_to_list (&exports, name);
2905 else if (! is_shared && which_pass == PASS_FIRST
2906 && import_flag
2907 && is_in_list(name, undefined.first))
2908 add_to_list (&imports, name);
2910 #endif
2911 continue;
2914 #if !defined(EXTENDED_COFF)
2915 if (debug)
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,
2919 name);
2920 #else
2921 if (debug)
2922 fprintf (stderr,
2923 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2924 symbol.iss, (long) symbol.value, symbol.index, name);
2925 #endif
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))
2933 char *name;
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. */
2940 if (*name == '.')
2941 ++name;
2942 add_to_list (&undefined, name);
2944 #endif
2947 #ifdef COLLECT_EXPORT_LIST
2948 else
2950 /* If archive contains both 32-bit and 64-bit objects,
2951 we want to skip objects in other mode so mismatch normal. */
2952 if (debug)
2953 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2954 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2956 #endif
2958 else
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);
2966 #else
2967 /* Otherwise we simply close ldptr. */
2968 (void) ldclose(ldptr);
2969 #endif
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. */
2977 static int
2978 use_import_list (prog_name)
2979 char *prog_name;
2981 char *p;
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))
2989 return 1;
2990 return 0;
2993 /* Given a library name without "lib" prefix, this function
2994 returns a full library name including a path. */
2995 static char *
2996 resolve_lib_name (name)
2997 char *name;
2999 char *lib_buf;
3000 int i, j, l = 0;
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
3017 without it. */
3018 char *p = "";
3019 if (list->prefix[strlen(list->prefix)-1] != '/')
3020 p = "/";
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);
3027 return (lib_buf);
3032 if (debug)
3033 fprintf (stderr, "not found\n");
3034 else
3035 fatal ("Library lib%s not found", name);
3036 return (NULL);
3039 /* Array of standard AIX libraries which should not
3040 be scanned for ctors/dtors. */
3041 static char* aix_std_libs[] = {
3042 "/unix",
3043 "/lib/libc.a",
3044 "/lib/libc_r.a",
3045 "/usr/lib/libc.a",
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",
3050 NULL
3053 /* This function checks the filename and returns 1
3054 if this name matches the location of a standard AIX library. */
3055 static int
3056 ignore_library (name)
3057 char *name;
3059 char **p = &aix_std_libs[0];
3060 while (*p++ != NULL)
3061 if (! strcmp (name, *p)) return 1;
3062 return 0;
3065 #endif
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 */
3091 } load_union_t;
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 */
3099 } load_all_t;
3101 /* Structure to contain information about a file mapped into memory. */
3103 struct file_info
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
3127 destructors.
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__. */
3135 static void
3136 scan_prog_file (prog_name, which_pass)
3137 char *prog_name;
3138 enum pass which_pass;
3140 char *obj;
3141 mo_header_t hdr;
3142 load_all_t *load_array;
3143 load_all_t *load_end;
3144 load_all_t *load_cmd;
3145 int symbol_load_cmds;
3146 off_t offset;
3147 int i;
3148 int num_syms;
3149 int status;
3150 char *str_sect;
3151 struct file_info *obj_file;
3152 int prog_fd;
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);
3158 if (prog_fd < 0)
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
3171 integers. */
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");
3184 #endif
3186 if (debug)
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. */
3202 if (rw)
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);
3206 load_hdr = ptr;
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;
3220 if (debug)
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)
3230 load_end--;
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)
3242 symbol_load_cmds++;
3244 if (debug)
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)
3260 continue;
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;
3275 if (name[0] != '_')
3276 continue;
3278 if (rw)
3280 char *n = name + strlen (name) - strlen (NAME__MAIN);
3282 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3283 continue;
3284 while (n != name)
3285 if (*--n != '_')
3286 continue;
3288 main_sym = sym;
3290 else
3292 switch (is_ctor_dtor (name))
3294 case 1:
3295 add_to_list (&constructors, name);
3296 break;
3298 case 2:
3299 add_to_list (&destructors, name);
3300 break;
3302 default: /* not a constructor or destructor */
3303 continue;
3307 if (debug)
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. */
3322 if (rw)
3324 load_union_t *load_map;
3325 size_t size;
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);
3339 if (debug)
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. */
3346 if (debug)
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;
3369 if (debug)
3370 print_header (&hdr);
3372 /* Write header */
3373 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3374 if (status != MO_HDR_CONV_SUCCESS)
3375 bad_header (status);
3377 if (debug)
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;
3387 if (debug)
3388 print_load_command (load_hdr, offset, i);
3390 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3391 offset += size;
3395 end_file (obj_file);
3397 if (close (prog_fd))
3398 fatal_perror ("closing %s", prog_name);
3400 if (debug)
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. */
3408 static void
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;
3421 int i;
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. */
3448 else
3450 mo_vm_addr_t addr = sym->si_value.abs_val;
3451 int found = 0;
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;
3465 found++;
3466 break;
3471 if (!found)
3472 fatal ("could not convert 0x%l.8x into a region", addr);
3475 if (debug)
3476 fprintf (stderr,
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. */
3488 static void
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");
3525 return;
3529 /* Print a short summary of a load command. */
3531 static void
3532 print_load_command (load_hdr, offset, number)
3533 load_union_t *load_hdr;
3534 size_t offset;
3535 int number;
3537 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3538 char *type_str = (char *) 0;
3540 switch (type)
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;
3555 fprintf (stderr,
3556 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3557 number,
3558 (long) load_hdr->hdr.ldci_cmd_size,
3559 (long) offset,
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);
3569 else
3571 char *region = "";
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;
3582 #endif
3585 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3586 type_str,
3587 (long) load_hdr->region.regc_vm_addr,
3588 (long) load_hdr->region.regc_vm_size,
3589 region);
3592 return;
3596 /* Fatal error when {en,de}code_mach_o_header fails. */
3598 static void
3599 bad_header (status)
3600 int status;
3602 char *msg = (char *) 0;
3604 switch (status)
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);
3616 else
3617 fatal ("%s", msg);
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);
3631 #ifdef USE_MMAP
3632 static int page_size;
3633 #endif
3635 if (fstat (fd, &stat_pkt) < 0)
3636 fatal_perror ("fstat %s", name);
3638 p->name = name;
3639 p->size = stat_pkt.st_size;
3640 p->rounded_size = stat_pkt.st_size;
3641 p->fd = fd;
3642 p->rw = rw;
3644 #ifdef USE_MMAP
3645 if (debug)
3646 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3648 if (page_size == 0)
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,
3657 0L);
3659 if (p->start != (char *) 0 && p->start != (char *) -1)
3660 p->use_mmap = 1;
3662 else
3663 #endif /* USE_MMAP */
3665 long len;
3667 if (debug)
3668 fprintf (stderr, "read %s\n", name);
3670 p->use_mmap = 0;
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);
3676 if (len < 0)
3677 fatal_perror ("read %s", name);
3679 if (len != p->size)
3680 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3683 return p;
3686 /* Do anything necessary to write a file back from memory. */
3688 static void
3689 end_file (ptr)
3690 struct file_info *ptr; /* file information block */
3692 #ifdef USE_MMAP
3693 if (ptr->use_mmap)
3695 if (ptr->rw)
3697 if (debug)
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);
3704 if (debug)
3705 fprintf (stderr, "munmap %s\n", ptr->name);
3707 if (munmap (ptr->start, ptr->size))
3708 fatal_perror ("munmap %s", ptr->name);
3710 else
3711 #endif /* USE_MMAP */
3713 if (ptr->rw)
3715 long len;
3717 if (debug)
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);
3724 if (len < 0)
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);
3731 free (ptr->start);
3734 free (ptr);
3737 #endif /* OBJECT_FORMAT_ROSE */