OSDN Git Service

oops
[pf3gnuchains/gcc-fork.git] / gcc / collect2.c
1 /* Collect static initialization info into data structures that can be
2    traversed by C++ initialization and finalization routines.
3    Copyright (C) 1992, 93-97, 1998 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).
7
8 This file is part of GNU CC.
9
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.
14
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.
19
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.  */
24
25
26 /* Build tables of static constructors and destructors and run ld.  */
27
28 #include "config.h"
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <sys/file.h>
35 #include <sys/stat.h>
36
37 #ifdef HAVE_STDLIB_H
38 #include <stdlib.h>
39 #endif
40
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44
45 #ifdef HAVE_STRING_H
46 #include <string.h>
47 #else
48 #ifdef HAVE_STRINGS_H
49 #include <strings.h>
50 #endif
51 #endif
52
53 #define COLLECT
54
55 #include "demangle.h"
56 #include "obstack.h"
57 #include "gansidecl.h"
58
59 #ifndef errno
60 extern int errno;
61 #endif
62
63 #ifndef HAVE_STRERROR
64 extern char *sys_errlist[];
65 extern int sys_nerr;
66 #else
67 char *strerror();
68 #endif
69
70 /* Obstack allocation and deallocation routines.  */
71 #define obstack_chunk_alloc xmalloc
72 #define obstack_chunk_free free
73
74 #ifdef USG
75 #define vfork fork
76 #endif
77
78 #ifndef R_OK
79 #define R_OK 4
80 #define W_OK 2
81 #define X_OK 1
82 #endif
83
84 #ifndef WIFSIGNALED
85 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
86 #endif
87 #ifndef WTERMSIG
88 #define WTERMSIG(S) ((S) & 0x7f)
89 #endif
90 #ifndef WIFEXITED
91 #define WIFEXITED(S) (((S) & 0xff) == 0)
92 #endif
93 #ifndef WEXITSTATUS
94 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
95 #endif
96
97 extern char *choose_temp_base ();
98 \f
99 /* On certain systems, we have code that works by scanning the object file
100    directly.  But this code uses system-specific header files and library
101    functions, so turn it off in a cross-compiler.  Likewise, the names of
102    the utilities are not correct for a cross-compiler; we have to hope that
103    cross-versions are in the proper directories.  */
104
105 #ifdef CROSS_COMPILE
106 #undef SUNOS4_SHARED_LIBRARIES
107 #undef OBJECT_FORMAT_COFF
108 #undef OBJECT_FORMAT_ROSE
109 #undef MD_EXEC_PREFIX
110 #undef REAL_LD_FILE_NAME
111 #undef REAL_NM_FILE_NAME
112 #undef REAL_STRIP_FILE_NAME
113 #endif
114
115 /* If we cannot use a special method, use the ordinary one:
116    run nm to find what symbols are present.
117    In a cross-compiler, this means you need a cross nm,
118    but that is not quite as unpleasant as special headers.  */
119
120 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
121 #define OBJECT_FORMAT_NONE
122 #endif
123
124 #ifdef OBJECT_FORMAT_COFF
125
126 #include <a.out.h>
127 #include <ar.h>
128
129 #ifdef UMAX
130 #include <sgs.h>
131 #endif
132
133 /* Many versions of ldfcn.h define these.  */
134 #ifdef FREAD
135 #undef FREAD
136 #undef FWRITE
137 #endif
138
139 #include <ldfcn.h>
140
141 /* Some systems have an ISCOFF macro, but others do not.  In some cases
142    the macro may be wrong.  MY_ISCOFF is defined in tm.h files for machines
143    that either do not have an ISCOFF macro in /usr/include or for those 
144    where it is wrong.  */
145
146 #ifndef MY_ISCOFF
147 #define MY_ISCOFF(X) ISCOFF (X)
148 #endif
149
150 #endif /* OBJECT_FORMAT_COFF */
151
152 #ifdef OBJECT_FORMAT_ROSE
153
154 #ifdef _OSF_SOURCE
155 #define USE_MMAP
156 #endif
157
158 #ifdef USE_MMAP
159 #include <sys/mman.h>
160 #endif
161
162 #include <unistd.h>
163 #include <mach_o_format.h>
164 #include <mach_o_header.h>
165 #include <mach_o_vals.h>
166 #include <mach_o_types.h>
167
168 #endif /* OBJECT_FORMAT_ROSE */
169
170 #ifdef OBJECT_FORMAT_NONE
171
172 /* Default flags to pass to nm.  */
173 #ifndef NM_FLAGS
174 #define NM_FLAGS "-p"
175 #endif
176
177 #endif /* OBJECT_FORMAT_NONE */
178
179 /* Some systems use __main in a way incompatible with its use in gcc, in these
180    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
181    give the same symbol without quotes for an alternative entry point.  You
182    must define both, or neither.  */
183 #ifndef NAME__MAIN
184 #define NAME__MAIN "__main"
185 #define SYMBOL__MAIN __main
186 #endif
187
188 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
189 #define SCAN_LIBRARIES
190 #endif
191
192 #ifdef USE_COLLECT2
193 int do_collecting = 1;
194 #else
195 int do_collecting = 0;
196 #endif
197 \f
198 /* Linked lists of constructor and destructor names.  */
199
200 struct id 
201 {
202   struct id *next;
203   int sequence;
204   char name[1];
205 };
206
207 struct head
208 {
209   struct id *first;
210   struct id *last;
211   int number;
212 };
213
214 /* Enumeration giving which pass this is for scanning the program file.  */
215
216 enum pass {
217   PASS_FIRST,                           /* without constructors */
218   PASS_OBJ,                             /* individual objects */
219   PASS_LIB,                             /* looking for shared libraries */
220   PASS_SECOND                           /* with constructors linked in */
221 };
222
223 #ifndef NO_SYS_SIGLIST
224 #ifndef SYS_SIGLIST_DECLARED
225 extern char *sys_siglist[];
226 #endif
227 #endif
228 extern char *version_string;
229
230 int vflag;                              /* true if -v */
231 static int rflag;                       /* true if -r */
232 static int strip_flag;                  /* true if -s */
233 #ifdef COLLECT_EXPORT_LIST
234 static int export_flag;                 /* true if -bE */
235 #endif
236
237 int debug;                              /* true if -debug */
238
239 static int shared_obj;                  /* true if -shared */
240
241 static int   temp_filename_length;      /* Length of temp_filename */
242 static char *temp_filename;             /* Base of temp filenames */
243 static char *c_file;                    /* <xxx>.c for constructor/destructor list.  */
244 static char *o_file;                    /* <xxx>.o for constructor/destructor list.  */
245 #ifdef COLLECT_EXPORT_LIST
246 static char *export_file;               /* <xxx>.x for AIX export list.  */
247 static char *import_file;               /* <xxx>.p for AIX import list.  */
248 #endif
249 char *ldout;                            /* File for ld errors.  */
250 static char *output_file;               /* Output file for ld.  */
251 static char *nm_file_name;              /* pathname of nm */
252 static char *ldd_file_name;             /* pathname of ldd (or equivalent) */
253 static char *strip_file_name;           /* pathname of strip */
254 char *c_file_name;                      /* pathname of gcc */
255 static char *initname, *fininame;       /* names of init and fini funcs */
256
257 static struct head constructors;        /* list of constructors found */
258 static struct head destructors;         /* list of destructors found */
259 #ifdef COLLECT_EXPORT_LIST
260 static struct head exports;             /* list of exported symbols */
261 static struct head imports;             /* list of imported symbols */
262 static struct head undefined;           /* list of undefined symbols */
263 #endif
264 static struct head frame_tables;        /* list of frame unwind info tables */
265
266 struct obstack temporary_obstack;
267 struct obstack permanent_obstack;
268 char * temporary_firstobj;
269
270 /* Defined in the automatically-generated underscore.c.  */
271 extern int prepends_underscore;
272
273 extern char *getenv ();
274 extern char *mktemp ();
275 extern FILE *fdopen ();
276
277 /* Structure to hold all the directories in which to search for files to
278    execute.  */
279
280 struct prefix_list
281 {
282   char *prefix;               /* String to prepend to the path.  */
283   struct prefix_list *next;   /* Next in linked list.  */
284 };
285
286 struct path_prefix
287 {
288   struct prefix_list *plist;  /* List of prefixes to try */
289   int max_len;                /* Max length of a prefix in PLIST */
290   char *name;                 /* Name of this list (used in config stuff) */
291 };
292
293 #ifdef COLLECT_EXPORT_LIST
294 /* Lists to keep libraries to be scanned for global constructors/destructors. */
295 static struct head libs;                    /* list of libraries */
296 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
297 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
298 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
299                                           &libpath_lib_dirs, NULL};
300 static char *libexts[3] = {"a", "so", NULL};  /* possible library extentions */
301 #endif
302
303 void collect_exit               PROTO((int));
304 void collect_execute            PROTO((char *, char **, char *));
305 void dump_file                  PROTO((char *));
306 static void handler             PROTO((int));
307 static int is_ctor_dtor         PROTO((char *));
308 static int is_in_prefix_list    PROTO((struct path_prefix *, char *, int));
309 static char *find_a_file        PROTO((struct path_prefix *, char *));
310 static void add_prefix          PROTO((struct path_prefix *, char *));
311 static void prefix_from_env     PROTO((char *, struct path_prefix *));
312 static void prefix_from_string  PROTO((char *, struct path_prefix *));
313 static void do_wait             PROTO((char *));
314 static void fork_execute        PROTO((char *, char **));
315 static void maybe_unlink        PROTO((char *));
316 static void add_to_list         PROTO((struct head *, char *));
317 static void write_list          PROTO((FILE *, char *, struct id *));
318 static void dump_list           PROTO((FILE *, char *, struct id *));
319 static void dump_prefix_list    PROTO((FILE *, char *, struct prefix_list *));
320 static int is_in_list           PROTO((char *, struct id *));
321 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
322 static void write_c_file        PROTO((FILE *, char *));
323 static void scan_prog_file      PROTO((char *, enum pass));
324 #ifdef SCAN_LIBRARIES
325 static void scan_libraries      PROTO((char *));
326 #endif
327 #ifdef COLLECT_EXPORT_LIST
328 static void write_export_file   PROTO((FILE *));
329 static void write_import_file   PROTO((FILE *));
330 static char *resolve_lib_name   PROTO((char *));
331 static int use_import_list      PROTO((char *));
332 static int ignore_library       PROTO((char *));
333 #endif
334
335 char *xcalloc ();
336 char *xmalloc ();
337
338 #ifdef NEED_DECLARATION_INDEX
339 extern char *index ();
340 #endif
341
342 #ifdef NEED_DECLARATION_RINDEX
343 extern char *rindex ();
344 #endif
345
346 #ifdef NEED_DECLARATION_FREE
347 extern void free ();
348 #endif
349 \f
350 #ifdef NO_DUP2
351 int
352 dup2 (oldfd, newfd)
353      int oldfd;
354      int newfd;
355 {
356   int fdtmp[256];
357   int fdx = 0;
358   int fd;
359  
360   if (oldfd == newfd)
361     return oldfd;
362   close (newfd);
363   while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
364     fdtmp[fdx++] = fd;
365   while (fdx > 0)
366     close (fdtmp[--fdx]);
367
368   return fd;
369 }
370 #endif
371
372 char *
373 my_strerror (e)
374      int e;
375 {
376
377 #ifdef HAVE_STRERROR
378   return strerror (e);
379
380 #else
381
382   static char buffer[30];
383   if (!e)
384     return "";
385
386   if (e > 0 && e < sys_nerr)
387     return sys_errlist[e];
388
389   sprintf (buffer, "Unknown error %d", e);
390   return buffer;
391 #endif
392 }
393 \f
394 /* Delete tempfiles and exit function.  */
395
396 void
397 collect_exit (status)
398      int status;
399 {
400   if (c_file != 0 && c_file[0])
401     maybe_unlink (c_file);
402
403   if (o_file != 0 && o_file[0])
404     maybe_unlink (o_file);
405
406 #ifdef COLLECT_EXPORT_LIST
407   if (export_file != 0 && export_file[0])
408     maybe_unlink (export_file);
409
410   if (import_file != 0 && import_file[0])
411     maybe_unlink (import_file);
412 #endif
413
414   if (ldout != 0 && ldout[0])
415     {
416       dump_file (ldout);
417       maybe_unlink (ldout);
418     }
419
420   if (status != 0 && output_file != 0 && output_file[0])
421     maybe_unlink (output_file);
422
423   exit (status);
424 }
425
426 \f
427 /* Die when sys call fails.  */
428
429 void
430 fatal_perror (string, arg1, arg2, arg3)
431      char *string, *arg1, *arg2, *arg3;
432 {
433   int e = errno;
434
435   fprintf (stderr, "collect2: ");
436   fprintf (stderr, string, arg1, arg2, arg3);
437   fprintf (stderr, ": %s\n", my_strerror (e));
438   collect_exit (FATAL_EXIT_CODE);
439 }
440
441 /* Just die.  */
442
443 void
444 fatal (string, arg1, arg2, arg3)
445      char *string, *arg1, *arg2, *arg3;
446 {
447   fprintf (stderr, "collect2: ");
448   fprintf (stderr, string, arg1, arg2, arg3);
449   fprintf (stderr, "\n");
450   collect_exit (FATAL_EXIT_CODE);
451 }
452
453 /* Write error message.  */
454
455 void
456 error (string, arg1, arg2, arg3, arg4)
457      char *string, *arg1, *arg2, *arg3, *arg4;
458 {
459   fprintf (stderr, "collect2: ");
460   fprintf (stderr, string, arg1, arg2, arg3, arg4);
461   fprintf (stderr, "\n");
462 }
463
464 /* In case obstack is linked in, and abort is defined to fancy_abort,
465    provide a default entry.  */
466
467 void
468 fancy_abort ()
469 {
470   fatal ("internal error");
471 }
472
473 \f
474 static void
475 handler (signo)
476      int signo;
477 {
478   if (c_file != 0 && c_file[0])
479     maybe_unlink (c_file);
480
481   if (o_file != 0 && o_file[0])
482     maybe_unlink (o_file);
483
484   if (ldout != 0 && ldout[0])
485     maybe_unlink (ldout);
486
487 #ifdef COLLECT_EXPORT_LIST
488   if (export_file != 0 && export_file[0])
489     maybe_unlink (export_file);
490
491   if (import_file != 0 && import_file[0])
492     maybe_unlink (import_file);
493 #endif
494
495   signal (signo, SIG_DFL);
496   kill (getpid (), signo);
497 }
498
499 \f
500 char *
501 xcalloc (size1, size2)
502      int size1, size2;
503 {
504   char *ptr = (char *) calloc (size1, size2);
505   if (ptr)
506     return ptr;
507
508   fatal ("out of memory");
509   return (char *) 0;
510 }
511
512 char *
513 xmalloc (size)
514      unsigned size;
515 {
516   char *ptr = (char *) malloc (size);
517   if (ptr)
518     return ptr;
519
520   fatal ("out of memory");
521   return (char *) 0;
522 }
523
524 char *
525 xrealloc (ptr, size)
526      char *ptr;
527      unsigned size;
528 {
529   register char *value = (char *) realloc (ptr, size);
530   if (value == 0)
531     fatal ("virtual memory exhausted");
532   return value;
533 }
534
535 int
536 file_exists (name)
537      char *name;
538 {
539   return access (name, R_OK) == 0;
540 }
541
542 /* Make a copy of a string INPUT with size SIZE.  */
543
544 char *
545 savestring (input, size)
546      char *input;
547      int size;
548 {
549   char *output = (char *) xmalloc (size + 1);
550   bcopy (input, output, size);
551   output[size] = 0;
552   return output;
553 }
554
555 /* Parse a reasonable subset of shell quoting syntax.  */
556
557 static char *
558 extract_string (pp)
559      char **pp;
560 {
561   char *p = *pp;
562   int backquote = 0;
563   int inside = 0;
564
565   for (;;)
566     {
567       char c = *p;
568       if (c == '\0')
569         break;
570       ++p;
571       if (backquote)
572         obstack_1grow (&temporary_obstack, c);
573       else if (! inside && c == ' ')
574         break;
575       else if (! inside && c == '\\')
576         backquote = 1;
577       else if (c == '\'')
578         inside = !inside;
579       else
580         obstack_1grow (&temporary_obstack, c);
581     }
582
583   obstack_1grow (&temporary_obstack, '\0');
584   *pp = p;
585   return obstack_finish (&temporary_obstack);
586 }
587 \f
588 void
589 dump_file (name)
590      char *name;
591 {
592   FILE *stream = fopen (name, "r");
593   int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
594
595   if (stream == 0)
596     return;
597   while (1)
598     {
599       int c;
600       while (c = getc (stream),
601              c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
602         obstack_1grow (&temporary_obstack, c);
603       if (obstack_object_size (&temporary_obstack) > 0)
604         {
605           char *word, *p, *result;
606           obstack_1grow (&temporary_obstack, '\0');
607           word = obstack_finish (&temporary_obstack);
608
609           if (*word == '.')
610             ++word, putc ('.', stderr);
611           p = word;
612           if (*p == '_' && prepends_underscore)
613             ++p;
614
615           if (no_demangle)
616             result = 0;
617           else
618             result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
619
620           if (result)
621             {
622               int diff;
623               fputs (result, stderr);
624
625               diff = strlen (word) - strlen (result);
626               while (diff > 0)
627                 --diff, putc (' ', stderr);
628               while (diff < 0 && c == ' ')
629                 ++diff, c = getc (stream);
630
631               free (result);
632             }
633           else
634             fputs (word, stderr);
635
636           fflush (stderr);
637           obstack_free (&temporary_obstack, temporary_firstobj);
638         }
639       if (c == EOF)
640         break;
641       putc (c, stderr);
642     }
643   fclose (stream);
644 }
645 \f
646 /* Decide whether the given symbol is:
647    a constructor (1), a destructor (2), or neither (0).  */
648
649 static int
650 is_ctor_dtor (s)
651      char *s;
652 {
653   struct names { char *name; int len; int ret; int two_underscores; };
654
655   register struct names *p;
656   register int ch;
657   register char *orig_s = s;
658
659   static struct names special[] = {
660 #ifdef NO_DOLLAR_IN_LABEL
661 #ifdef NO_DOT_IN_LABEL
662     { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
663     { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
664     { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
665 #else
666     { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
667     { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
668     { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
669 #endif
670 #else
671     { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
672     { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
673     { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
674 #endif
675     { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
676     { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
677 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
678                          cfront has its own linker procedure to collect them;
679                          if collect2 gets them too, they get collected twice
680                          when the cfront procedure is run and the compiler used
681                          for linking happens to be GCC.  */
682     { "sti__", sizeof ("sti__")-1, 1, 1 },
683     { "std__", sizeof ("std__")-1, 2, 1 },
684 #endif /* CFRONT_LOSSAGE */
685     { NULL, 0, 0, 0 }
686   };
687
688   while ((ch = *s) == '_')
689     ++s;
690
691   if (s == orig_s)
692     return 0;
693
694   for (p = &special[0]; p->len > 0; p++)
695     {
696       if (ch == p->name[0]
697           && (!p->two_underscores || ((s - orig_s) >= 2))
698           && strncmp(s, p->name, p->len) == 0)
699         {
700           return p->ret;
701         }
702     }
703   return 0;
704 }
705 \f
706 /* Routine to add variables to the environment.  */
707
708 #ifndef HAVE_PUTENV
709
710 int
711 putenv (str)
712      char *str;
713 {
714 #ifndef VMS                     /* nor about VMS */
715
716   extern char **environ;
717   char **old_environ = environ;
718   char **envp;
719   int num_envs = 0;
720   int name_len = 1;
721   char *p = str;
722   int ch;
723
724   while ((ch = *p++) != '\0' && ch != '=')
725     name_len++;
726
727   if (!ch)
728     abort ();
729
730   /* Search for replacing an existing environment variable, and
731      count the number of total environment variables.  */
732   for (envp = old_environ; *envp; envp++)
733     {
734       num_envs++;
735       if (!strncmp (str, *envp, name_len))
736         {
737           *envp = str;
738           return 0;
739         }
740     }
741
742   /* Add a new environment variable */
743   environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
744   *environ = str;
745   bcopy ((char *) old_environ, (char *) (environ + 1),
746          sizeof (char *) * (num_envs+1));
747
748   return 0;
749 #endif  /* VMS */
750 }
751
752 #endif  /* HAVE_PUTENV */
753 \f
754 /* By default, colon separates directories in a path.  */
755 #ifndef PATH_SEPARATOR
756 #define PATH_SEPARATOR ':'
757 #endif
758
759 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
760    and one from the PATH variable.  */
761
762 static struct path_prefix cpath, path;
763
764 #ifdef CROSS_COMPILE
765 /* This is the name of the target machine.  We use it to form the name
766    of the files to execute.  */
767
768 static char *target_machine = TARGET_MACHINE;
769 #endif
770
771 /* Names under which we were executed.  Never return one of those files in our
772    searches.  */
773
774 static struct path_prefix our_file_names;
775 \f
776 /* Determine if STRING is in PPREFIX.
777
778    This utility is currently only used to look up file names.  Prefix lists
779    record directory names.  This matters to us because the latter has a 
780    trailing slash, so I've added a flag to handle both.  */
781
782 static int
783 is_in_prefix_list (pprefix, string, filep)
784      struct path_prefix *pprefix;
785      char *string;
786      int filep;
787 {
788   struct prefix_list *pl;
789
790   if (filep)
791     {
792       int len = strlen (string);
793
794       for (pl = pprefix->plist; pl; pl = pl->next)
795         {
796           if (strncmp (pl->prefix, string, len) == 0
797               && strcmp (pl->prefix + len, "/") == 0)
798             return 1;
799         }
800     }
801   else
802     {
803       for (pl = pprefix->plist; pl; pl = pl->next)
804         {
805           if (strcmp (pl->prefix, string) == 0)
806             return 1;
807         }
808     }
809
810   return 0;
811 }
812
813 /* Search for NAME using prefix list PPREFIX.  We only look for executable
814    files. 
815
816    Return 0 if not found, otherwise return its name, allocated with malloc.  */
817
818 static char *
819 find_a_file (pprefix, name)
820      struct path_prefix *pprefix;
821      char *name;
822 {
823   char *temp;
824   struct prefix_list *pl;
825   int len = pprefix->max_len + strlen (name) + 1;
826
827 #ifdef EXECUTABLE_SUFFIX
828   len += strlen (EXECUTABLE_SUFFIX);
829 #endif
830
831   temp = xmalloc (len);
832
833   /* Determine the filename to execute (special case for absolute paths).  */
834
835   if (*name == '/')
836     {
837       if (access (name, X_OK) == 0)
838         {
839           strcpy (temp, name);
840           return temp;
841         }
842     }
843   else
844     for (pl = pprefix->plist; pl; pl = pl->next)
845       {
846         strcpy (temp, pl->prefix);
847         strcat (temp, name);
848         if (! is_in_prefix_list (&our_file_names, temp, 1)
849             /* This is a kludge, but there seems no way around it.  */
850             && strcmp (temp, "./ld") != 0
851             && access (temp, X_OK) == 0)
852           return temp;
853
854 #ifdef EXECUTABLE_SUFFIX
855         /* Some systems have a suffix for executable files.
856            So try appending that.  */
857         strcat (temp, EXECUTABLE_SUFFIX);
858         if (! is_in_prefix_list (&our_file_names, temp, 1)
859             && access (temp, X_OK) == 0)
860           return temp;
861 #endif
862       }
863
864   free (temp);
865   return 0;
866 }
867
868 /* Add an entry for PREFIX to prefix list PPREFIX.  */
869
870 static void
871 add_prefix (pprefix, prefix)
872      struct path_prefix *pprefix;
873      char *prefix;
874 {
875   struct prefix_list *pl, **prev;
876   int len;
877
878   if (pprefix->plist)
879     {
880       for (pl = pprefix->plist; pl->next; pl = pl->next)
881         ;
882       prev = &pl->next;
883     }
884   else
885     prev = &pprefix->plist;
886
887   /* Keep track of the longest prefix */
888
889   len = strlen (prefix);
890   if (len > pprefix->max_len)
891     pprefix->max_len = len;
892
893   pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
894   pl->prefix = savestring (prefix, len);
895
896   if (*prev)
897     pl->next = *prev;
898   else
899     pl->next = (struct prefix_list *) 0;
900   *prev = pl;
901 }
902 \f
903 /* Take the value of the environment variable ENV, break it into a path, and
904    add of the entries to PPREFIX.  */
905
906 static void
907 prefix_from_env (env, pprefix)
908      char *env;
909      struct path_prefix *pprefix;
910 {
911   char *p = getenv (env);
912
913   if (p)
914     prefix_from_string (p, pprefix);
915 }
916
917 static void
918 prefix_from_string (p, pprefix)
919      char *p;
920      struct path_prefix *pprefix;
921 {
922   char *startp, *endp;
923   char *nstore = (char *) xmalloc (strlen (p) + 3);
924
925   startp = endp = p;
926   while (1)
927     {
928       if (*endp == PATH_SEPARATOR || *endp == 0)
929         {
930           strncpy (nstore, startp, endp-startp);
931           if (endp == startp)
932             {
933               strcpy (nstore, "./");
934             }
935           else if (endp[-1] != '/')
936             {
937               nstore[endp-startp] = '/';
938               nstore[endp-startp+1] = 0;
939             }
940           else
941             nstore[endp-startp] = 0;
942
943           add_prefix (pprefix, nstore);
944           if (*endp == 0)
945             break;
946           endp = startp = endp + 1;
947         }
948       else
949         endp++;
950     }
951 }
952 \f
953 /* Main program.  */
954
955 int
956 main (argc, argv)
957      int argc;
958      char *argv[];
959 {
960   char *ld_suffix       = "ld";
961   char *full_ld_suffix  = ld_suffix;
962   char *real_ld_suffix  = "real-ld";
963 #ifdef CROSS_COMPILE
964   char *full_real_ld_suffix = real_ld_suffix;
965 #endif
966   char *collect_ld_suffix = "collect-ld";
967   char *nm_suffix       = "nm";
968   char *full_nm_suffix  = nm_suffix;
969   char *gnm_suffix      = "gnm";
970   char *full_gnm_suffix = gnm_suffix;
971 #ifdef LDD_SUFFIX
972   char *ldd_suffix      = LDD_SUFFIX;
973   char *full_ldd_suffix = ldd_suffix;
974 #endif
975   char *strip_suffix    = "strip";
976   char *full_strip_suffix = strip_suffix;
977   char *gstrip_suffix   = "gstrip";
978   char *full_gstrip_suffix = gstrip_suffix;
979   char *arg;
980   FILE *outf;
981 #ifdef COLLECT_EXPORT_LIST
982   FILE *exportf;
983   FILE *importf;
984 #endif
985   char *ld_file_name;
986   char *collect_name;
987   char *collect_names;
988   char *p;
989   char **c_argv;
990   char **c_ptr;
991   char **ld1_argv       = (char **) xcalloc (sizeof (char *), argc+3);
992   char **ld1            = ld1_argv;
993   char **ld2_argv       = (char **) xcalloc (sizeof (char *), argc+6);
994   char **ld2            = ld2_argv;
995   char **object_lst     = (char **) xcalloc (sizeof (char *), argc);
996   char **object         = object_lst;
997   int first_file;
998   int num_c_args        = argc+7;
999
1000 #ifdef DEBUG
1001   debug = 1;
1002   vflag = 1;
1003 #endif
1004
1005 #ifndef DEFAULT_A_OUT_NAME
1006   output_file = "a.out";
1007 #else
1008   output_file = DEFAULT_A_OUT_NAME;
1009 #endif
1010
1011   obstack_begin (&temporary_obstack, 0);
1012   obstack_begin (&permanent_obstack, 0);
1013   temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
1014   current_demangling_style = gnu_demangling;
1015
1016   /* We must check that we do not call ourselves in an infinite
1017      recursion loop. We append the name used for us to the COLLECT_NAMES
1018      environment variable.
1019
1020      In practice, collect will rarely invoke itself.  This can happen now
1021      that we are no longer called gld.  A perfect example is when running
1022      gcc in a build directory that has been installed.  When looking for
1023      ld, we will find our installed version and believe that's the real ld.  */
1024
1025   /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
1026      previous version of collect (the one that used COLLECT_NAME and only
1027      handled two levels of recursion).  If we do not we may mutually recurse
1028      forever.  This can happen (I think) when bootstrapping the old version
1029      and a new one is installed (rare, but we should handle it).
1030      ??? Hopefully references to COLLECT_NAME can be removed at some point.  */
1031
1032   collect_name = (char *) getenv ("COLLECT_NAME");
1033   collect_names = (char *) getenv ("COLLECT_NAMES");
1034
1035   p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
1036                         + (collect_name ? strlen (collect_name) + 1 : 0)
1037                         + (collect_names ? strlen (collect_names) + 1 : 0)
1038                         + strlen (argv[0]) + 1);
1039   strcpy (p, "COLLECT_NAMES=");
1040   if (collect_name != 0)
1041     sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
1042   if (collect_names != 0)
1043     sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
1044   strcat (p, argv[0]);
1045   putenv (p);
1046
1047   prefix_from_env ("COLLECT_NAMES", &our_file_names);
1048
1049   /* Set environment variable COLLECT_NAME to our name so the previous version
1050      of collect will not find us.  If it does we will mutually recurse forever.
1051      This can happen when bootstrapping the new version and an old version is
1052      installed.
1053      ??? Hopefully this bit of code can be removed at some point.  */
1054
1055   p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
1056   sprintf (p, "COLLECT_NAME=%s", argv[0]);
1057   putenv (p);
1058
1059   p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1060   while (p && *p)
1061     {
1062       char *q = extract_string (&p);
1063       if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1064         num_c_args++;
1065     }
1066   obstack_free (&temporary_obstack, temporary_firstobj);
1067   ++num_c_args;
1068
1069   c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1070
1071   if (argc < 2)
1072     fatal ("no arguments");
1073
1074 #ifdef SIGQUIT
1075   if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1076     signal (SIGQUIT, handler);
1077 #endif
1078   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1079     signal (SIGINT, handler);
1080 #ifdef SIGALRM
1081   if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1082     signal (SIGALRM, handler);
1083 #endif
1084 #ifdef SIGHUP
1085   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1086     signal (SIGHUP, handler);
1087 #endif
1088   if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1089     signal (SIGSEGV, handler);
1090 #ifdef SIGBUS
1091   if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1092     signal (SIGBUS, handler);
1093 #endif
1094
1095   /* Extract COMPILER_PATH and PATH into our prefix list.  */
1096   prefix_from_env ("COMPILER_PATH", &cpath);
1097   prefix_from_env ("PATH", &path);
1098
1099 #ifdef CROSS_COMPILE
1100   /* If we look for a program in the compiler directories, we just use
1101      the short name, since these directories are already system-specific.
1102      But it we look for a took in the system directories, we need to
1103      qualify the program name with the target machine.  */
1104
1105   full_ld_suffix
1106     = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1107   strcpy (full_ld_suffix, target_machine);
1108   strcat (full_ld_suffix, "-");
1109   strcat (full_ld_suffix, ld_suffix);
1110
1111   full_real_ld_suffix
1112     = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1113   strcpy (full_real_ld_suffix, target_machine);
1114   strcat (full_real_ld_suffix, "-");
1115   strcat (full_real_ld_suffix, real_ld_suffix);
1116
1117 #if 0
1118   full_gld_suffix
1119     = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1120   strcpy (full_gld_suffix, target_machine);
1121   strcat (full_gld_suffix, "-");
1122   strcat (full_gld_suffix, gld_suffix);
1123 #endif
1124
1125   full_nm_suffix
1126     = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1127   strcpy (full_nm_suffix, target_machine);
1128   strcat (full_nm_suffix, "-");
1129   strcat (full_nm_suffix, nm_suffix);
1130
1131   full_gnm_suffix
1132     = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1133   strcpy (full_gnm_suffix, target_machine);
1134   strcat (full_gnm_suffix, "-");
1135   strcat (full_gnm_suffix, gnm_suffix);
1136
1137 #ifdef LDD_SUFFIX
1138   full_ldd_suffix
1139     = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1140   strcpy (full_ldd_suffix, target_machine);
1141   strcat (full_ldd_suffix, "-");
1142   strcat (full_ldd_suffix, ldd_suffix);
1143 #endif
1144
1145   full_strip_suffix
1146     = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1147   strcpy (full_strip_suffix, target_machine);
1148   strcat (full_strip_suffix, "-");
1149   strcat (full_strip_suffix, strip_suffix);
1150   
1151   full_gstrip_suffix
1152     = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1153   strcpy (full_gstrip_suffix, target_machine);
1154   strcat (full_gstrip_suffix, "-");
1155   strcat (full_gstrip_suffix, gstrip_suffix);
1156 #endif /* CROSS_COMPILE */
1157
1158   /* Try to discover a valid linker/nm/strip to use.  */
1159
1160   /* Maybe we know the right file to use (if not cross).  */
1161 #ifdef REAL_LD_FILE_NAME
1162   ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1163   if (ld_file_name == 0)
1164 #endif
1165   /* Search the (target-specific) compiler dirs for ld'.  */
1166   ld_file_name = find_a_file (&cpath, real_ld_suffix);
1167   /* Likewise for `collect-ld'.  */
1168   if (ld_file_name == 0)
1169     ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1170   /* Search the compiler directories for `ld'.  We have protection against
1171      recursive calls in find_a_file.  */
1172   if (ld_file_name == 0)
1173     ld_file_name = find_a_file (&cpath, ld_suffix);
1174   /* Search the ordinary system bin directories
1175      for `ld' (if native linking) or `TARGET-ld' (if cross).  */
1176   if (ld_file_name == 0)
1177     ld_file_name = find_a_file (&path, full_ld_suffix);
1178
1179   /* If we've invoked ourselves, try again with LD_FILE_NAME.  */
1180
1181   if (collect_names != 0)
1182     {
1183       if (ld_file_name != 0)
1184         {
1185           argv[0] = ld_file_name;
1186           execvp (argv[0], argv);
1187         }
1188       fatal ("cannot find `ld'");
1189     }
1190
1191 #ifdef REAL_NM_FILE_NAME
1192   nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1193   if (nm_file_name == 0)
1194 #endif
1195   nm_file_name = find_a_file (&cpath, gnm_suffix);
1196   if (nm_file_name == 0)
1197     nm_file_name = find_a_file (&path, full_gnm_suffix);
1198   if (nm_file_name == 0)
1199     nm_file_name = find_a_file (&cpath, nm_suffix);
1200   if (nm_file_name == 0)
1201     nm_file_name = find_a_file (&path, full_nm_suffix);
1202
1203 #ifdef LDD_SUFFIX
1204   ldd_file_name = find_a_file (&cpath, ldd_suffix);
1205   if (ldd_file_name == 0)
1206     ldd_file_name = find_a_file (&path, full_ldd_suffix);
1207 #endif
1208
1209 #ifdef REAL_STRIP_FILE_NAME
1210   strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1211   if (strip_file_name == 0)
1212 #endif
1213   strip_file_name = find_a_file (&cpath, gstrip_suffix);
1214   if (strip_file_name == 0)
1215     strip_file_name = find_a_file (&path, full_gstrip_suffix);
1216   if (strip_file_name == 0)
1217     strip_file_name = find_a_file (&cpath, strip_suffix);
1218   if (strip_file_name == 0)
1219     strip_file_name = find_a_file (&path, full_strip_suffix);
1220
1221   /* Determine the full path name of the C compiler to use.  */
1222   c_file_name = getenv ("COLLECT_GCC");
1223   if (c_file_name == 0)
1224     {
1225 #ifdef CROSS_COMPILE
1226       c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1227       strcpy (c_file_name, target_machine);
1228       strcat (c_file_name, "-gcc");
1229 #else
1230       c_file_name = "gcc";
1231 #endif
1232     }
1233
1234   p = find_a_file (&cpath, c_file_name);
1235
1236   /* Here it should be safe to use the system search path since we should have
1237      already qualified the name of the compiler when it is needed.  */
1238   if (p == 0)
1239     p = find_a_file (&path, c_file_name);
1240
1241   if (p)
1242     c_file_name = p;
1243
1244   *ld1++ = *ld2++ = ld_file_name;
1245
1246   /* Make temp file names.  */
1247   temp_filename = choose_temp_base ();
1248   temp_filename_length = strlen (temp_filename);
1249   c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1250   o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1251 #ifdef COLLECT_EXPORT_LIST
1252   export_file = xmalloc (temp_filename_length + sizeof (".x"));
1253   import_file = xmalloc (temp_filename_length + sizeof (".p"));
1254 #endif
1255   ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1256   sprintf (ldout, "%s.ld", temp_filename);
1257   sprintf (c_file, "%s.c", temp_filename);
1258   sprintf (o_file, "%s.o", temp_filename);
1259 #ifdef COLLECT_EXPORT_LIST
1260   sprintf (export_file, "%s.x", temp_filename);
1261   sprintf (import_file, "%s.p", temp_filename);
1262 #endif
1263   *c_ptr++ = c_file_name;
1264   *c_ptr++ = "-c";
1265   *c_ptr++ = "-o";
1266   *c_ptr++ = o_file;
1267
1268 #ifdef COLLECT_EXPORT_LIST
1269   /* Generate a list of directories from LIBPATH.  */
1270   prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1271   /* Add to this list also two standard directories where
1272      AIX loader always searches for libraries.  */
1273   add_prefix (&libpath_lib_dirs, "/lib");
1274   add_prefix (&libpath_lib_dirs, "/usr/lib");
1275 #endif
1276
1277   /* Get any options that the upper GCC wants to pass to the sub-GCC.  
1278
1279      AIX support needs to know if -shared has been specified before
1280      parsing commandline arguments.  */
1281
1282   p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1283   while (p && *p)
1284     {
1285       char *q = extract_string (&p);
1286       if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1287         *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1288       if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1289         shared_obj = 1;
1290     }
1291   obstack_free (&temporary_obstack, temporary_firstobj);
1292   *c_ptr++ = "-fno-exceptions";
1293
1294   /* !!! When GCC calls collect2,
1295      it does not know whether it is calling collect2 or ld.
1296      So collect2 cannot meaningfully understand any options
1297      except those ld understands.
1298      If you propose to make GCC pass some other option,
1299      just imagine what will happen if ld is really ld!!!  */
1300
1301   /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
1302   /* After the first file, put in the c++ rt0.  */
1303
1304   first_file = 1;
1305   while ((arg = *++argv) != (char *) 0)
1306     {
1307       *ld1++ = *ld2++ = arg;
1308
1309       if (arg[0] == '-')
1310         {
1311           switch (arg[1])
1312             {
1313 #ifdef COLLECT_EXPORT_LIST
1314             /* We want to disable automatic exports on AIX when user
1315                explicitly puts an export list in command line */
1316             case 'b':
1317               if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1318                 export_flag = 1;
1319               break;
1320 #endif
1321
1322             case 'd':
1323               if (!strcmp (arg, "-debug"))
1324                 {
1325                   debug = 1;
1326                   vflag = 1;
1327                   ld1--;
1328                   ld2--;
1329                 }
1330               break;
1331
1332             case 'l':
1333               if (first_file)
1334                 {
1335                   /* place o_file BEFORE this argument! */
1336                   first_file = 0;
1337                   ld2--;
1338                   *ld2++ = o_file;
1339                   *ld2++ = arg;
1340                 }
1341 #ifdef COLLECT_EXPORT_LIST
1342               {
1343                 /* Resolving full library name.  */
1344                 char *s = resolve_lib_name (arg+2);
1345
1346                 /* If we will use an import list for this library,
1347                    we should exclude it from ld args.  */
1348                 if (use_import_list (s))
1349                   {
1350                     ld1--;
1351                     ld2--;
1352                   }
1353
1354                 /* Saving a full library name.  */
1355                 add_to_list (&libs, s);
1356               }
1357 #endif
1358               break;
1359
1360 #ifdef COLLECT_EXPORT_LIST
1361             /* Saving directories where to search for libraries.  */
1362             case 'L':
1363               add_prefix (&cmdline_lib_dirs, arg+2);
1364               break;
1365 #endif
1366
1367             case 'o':
1368               if (arg[2] == '\0')
1369                 output_file = *ld1++ = *ld2++ = *++argv;
1370               else
1371                 output_file = &arg[2];
1372               break;
1373
1374             case 'r':
1375               if (arg[2] == '\0')
1376                 rflag = 1;
1377               break;
1378
1379             case 's':
1380               if (arg[2] == '\0' && do_collecting)
1381                 {
1382                   /* We must strip after the nm run, otherwise C++ linking
1383                      will not work.  Thus we strip in the second ld run, or
1384                      else with strip if there is no second ld run.  */
1385                   strip_flag = 1;
1386                   ld1--;
1387                 }
1388               break;
1389
1390             case 'v':
1391               if (arg[2] == '\0')
1392                 vflag = 1;
1393               break;
1394             }
1395         }
1396       else if ((p = rindex (arg, '.')) != (char *) 0
1397                && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1398                    || strcmp (p, ".so") == 0))
1399         {
1400           if (first_file)
1401             {
1402               first_file = 0;
1403               if (p[1] == 'o')
1404                 *ld2++ = o_file;
1405               else
1406                 {
1407                   /* place o_file BEFORE this argument! */
1408                   ld2--;
1409                   *ld2++ = o_file;
1410                   *ld2++ = arg;
1411                 }
1412             }
1413           if (p[1] == 'o')
1414             *object++ = arg;
1415 #ifdef COLLECT_EXPORT_LIST
1416           /* libraries can be specified directly, i.e. without -l flag.  */
1417           else
1418             { 
1419               /* If we will use an import list for this library,
1420                  we should exclude it from ld args.  */
1421               if (use_import_list (arg))
1422                 {
1423                   ld1--;
1424                   ld2--;
1425                 }
1426
1427               /* Saving a full library name.  */
1428               add_to_list (&libs, arg);
1429             }
1430 #endif
1431         }
1432     }
1433
1434 #ifdef COLLECT_EXPORT_LIST
1435   /* This is added only for debugging purposes.  */
1436   if (debug)
1437     {
1438       fprintf (stderr, "List of libraries:\n");
1439       dump_list (stderr, "\t", libs.first);
1440     }
1441
1442   /* The AIX linker will discard static constructors in object files if
1443      nothing else in the file is referenced, so look at them first.  */
1444   {
1445       char **export_object_lst = object_lst;
1446       while (export_object_lst < object)
1447         scan_prog_file (*export_object_lst++, PASS_OBJ);
1448   }
1449   {
1450     struct id *list = libs.first;
1451     for (; list; list = list->next)
1452       scan_prog_file (list->name, PASS_FIRST);
1453   }
1454   {
1455     char *buf1 = alloca (strlen (export_file) + 5);
1456     char *buf2 = alloca (strlen (import_file) + 5);
1457     sprintf (buf1, "-bE:%s", export_file);
1458     sprintf (buf2, "-bI:%s", import_file);
1459     *ld1++ = buf1;
1460     *ld2++ = buf1;
1461     *ld1++ = buf2;
1462     *ld2++ = buf2;
1463     exportf = fopen (export_file, "w");
1464     if (exportf == (FILE *) 0)
1465       fatal_perror ("%s", export_file);
1466     write_export_file (exportf);
1467     if (fclose (exportf))
1468       fatal_perror ("closing %s", export_file);
1469     importf = fopen (import_file, "w");
1470     if (importf == (FILE *) 0)
1471       fatal_perror ("%s", import_file);
1472     write_import_file (importf);
1473     if (fclose (importf))
1474       fatal_perror ("closing %s", import_file);
1475   }
1476 #endif
1477
1478   *c_ptr++ = c_file;
1479   *object = *c_ptr = *ld1 = (char *) 0;
1480
1481   if (vflag)
1482     {
1483       fprintf (stderr, "collect2 version %s", version_string);
1484 #ifdef TARGET_VERSION
1485       TARGET_VERSION;
1486 #endif
1487       fprintf (stderr, "\n");
1488     }
1489
1490   if (debug)
1491     {
1492       char *ptr;
1493       fprintf (stderr, "ld_file_name        = %s\n",
1494                (ld_file_name ? ld_file_name : "not found"));
1495       fprintf (stderr, "c_file_name         = %s\n",
1496                (c_file_name ? c_file_name : "not found"));
1497       fprintf (stderr, "nm_file_name        = %s\n",
1498                (nm_file_name ? nm_file_name : "not found"));
1499 #ifdef LDD_SUFFIX
1500       fprintf (stderr, "ldd_file_name       = %s\n",
1501                (ldd_file_name ? ldd_file_name : "not found"));
1502 #endif
1503       fprintf (stderr, "strip_file_name     = %s\n",
1504                (strip_file_name ? strip_file_name : "not found"));
1505       fprintf (stderr, "c_file              = %s\n",
1506                (c_file ? c_file : "not found"));
1507       fprintf (stderr, "o_file              = %s\n",
1508                (o_file ? o_file : "not found"));
1509
1510       ptr = getenv ("COLLECT_NAMES");
1511       if (ptr)
1512         fprintf (stderr, "COLLECT_NAMES       = %s\n", ptr);
1513
1514       ptr = getenv ("COLLECT_GCC_OPTIONS");
1515       if (ptr)
1516         fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1517
1518       ptr = getenv ("COLLECT_GCC");
1519       if (ptr)
1520         fprintf (stderr, "COLLECT_GCC         = %s\n", ptr);
1521
1522       ptr = getenv ("COMPILER_PATH");
1523       if (ptr)
1524         fprintf (stderr, "COMPILER_PATH       = %s\n", ptr);
1525
1526       ptr = getenv ("LIBRARY_PATH");
1527       if (ptr)
1528         fprintf (stderr, "LIBRARY_PATH        = %s\n", ptr);
1529
1530       fprintf (stderr, "\n");
1531     }
1532
1533   /* Load the program, searching all libraries and attempting to provide
1534      undefined symbols from repository information.  */
1535
1536   /* On AIX we do this later.  */
1537 #ifdef COLLECT_EXPORT_LIST
1538   do_tlink (ld1_argv, object_lst); 
1539 #endif
1540
1541   /* If -r or they will be run via some other method, do not build the
1542      constructor or destructor list, just return now.  */
1543   if (rflag || ! do_collecting)
1544     {
1545 #ifdef COLLECT_EXPORT_LIST
1546       /* But make sure we delete the export file we may have created.  */
1547       if (export_file != 0 && export_file[0])
1548         maybe_unlink (export_file);
1549       if (import_file != 0 && import_file[0])
1550         maybe_unlink (import_file);
1551 #endif
1552       return 0;
1553     }
1554
1555   /* Examine the namelist with nm and search it for static constructors
1556      and destructors to call.
1557      Write the constructor and destructor tables to a .s file and reload.  */
1558
1559   /* On AIX we already done scanning for global constructors/destructors.  */
1560 #ifndef COLLECT_EXPORT_LIST
1561   scan_prog_file (output_file, PASS_FIRST);
1562 #endif
1563
1564 #ifdef SCAN_LIBRARIES
1565   scan_libraries (output_file);
1566 #endif
1567
1568   if (debug)
1569     {
1570       fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1571       fprintf (stderr, "%d destructor(s)  found\n", destructors.number);
1572     }
1573
1574   if (constructors.number == 0 && destructors.number == 0
1575       && frame_tables.number == 0
1576 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1577       /* If we will be running these functions ourselves, we want to emit
1578          stubs into the shared library so that we do not have to relink
1579          dependent programs when we add static objects.  */
1580       && ! shared_obj
1581 #endif
1582       )
1583     {
1584 #ifdef COLLECT_EXPORT_LIST
1585       /* Doing tlink without additional code generation */
1586       do_tlink (ld1_argv, object_lst);
1587 #endif
1588       /* Strip now if it was requested on the command line.  */
1589       if (strip_flag)
1590         {
1591           char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1592           strip_argv[0] = strip_file_name;
1593           strip_argv[1] = output_file;
1594           strip_argv[2] = (char *) 0;
1595           fork_execute ("strip", strip_argv);
1596         }
1597
1598 #ifdef COLLECT_EXPORT_LIST
1599       maybe_unlink (export_file);
1600       maybe_unlink (import_file);
1601 #endif
1602       return 0;
1603     }
1604
1605   maybe_unlink(output_file);
1606   outf = fopen (c_file, "w");
1607   if (outf == (FILE *) 0)
1608     fatal_perror ("%s", c_file);
1609
1610   write_c_file (outf, c_file);
1611
1612   if (fclose (outf))
1613     fatal_perror ("closing %s", c_file);
1614
1615   /* Tell the linker that we have initializer and finalizer functions.  */
1616 #ifdef LD_INIT_SWITCH
1617   *ld2++ = LD_INIT_SWITCH;
1618   *ld2++ = initname;
1619   *ld2++ = LD_FINI_SWITCH;
1620   *ld2++ = fininame;
1621 #endif
1622   *ld2 = (char*) 0;
1623
1624 #ifdef COLLECT_EXPORT_LIST
1625   if (shared_obj)
1626     {
1627       add_to_list (&exports, initname);
1628       add_to_list (&exports, fininame);
1629       add_to_list (&exports, "_GLOBAL__DI");
1630       add_to_list (&exports, "_GLOBAL__DD");
1631       exportf = fopen (export_file, "w");
1632       if (exportf == (FILE *) 0)
1633         fatal_perror ("%s", export_file);
1634       write_export_file (exportf);
1635       if (fclose (exportf))
1636         fatal_perror ("closing %s", export_file);
1637     }
1638 #endif
1639
1640   if (debug)
1641     {
1642       fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1643                output_file, c_file);
1644       write_c_file (stderr, "stderr");
1645       fprintf (stderr, "========== end of c_file\n\n");
1646 #ifdef COLLECT_EXPORT_LIST
1647       fprintf (stderr, "\n========== export_file = %s\n", export_file);
1648       write_export_file (stderr);
1649       fprintf (stderr, "========== end of export_file\n\n");
1650 #endif
1651     }
1652
1653   /* Assemble the constructor and destructor tables.
1654      Link the tables in with the rest of the program.  */
1655
1656   fork_execute ("gcc",  c_argv);
1657 #ifdef COLLECT_EXPORT_LIST
1658   /* On AIX we must call tlink because of possible templates resolution */
1659   do_tlink (ld2_argv, object_lst);
1660 #else
1661   /* Otherwise, simply call ld because tlink is already done */
1662   fork_execute ("ld", ld2_argv);
1663
1664   /* Let scan_prog_file do any final mods (OSF/rose needs this for
1665      constructors/destructors in shared libraries.  */
1666   scan_prog_file (output_file, PASS_SECOND);
1667 #endif 
1668
1669   maybe_unlink (c_file);
1670   maybe_unlink (o_file);
1671
1672 #ifdef COLLECT_EXPORT_LIST
1673   maybe_unlink (export_file);
1674   maybe_unlink (import_file);
1675 #endif
1676
1677   return 0;
1678 }
1679
1680 \f
1681 /* Wait for a process to finish, and exit if a non-zero status is found.  */
1682
1683 int
1684 collect_wait (prog)
1685      char *prog;
1686 {
1687   int status;
1688
1689   wait (&status);
1690   if (status)
1691     {
1692       if (WIFSIGNALED (status))
1693         {
1694           int sig = WTERMSIG (status);
1695 #ifdef NO_SYS_SIGLIST
1696           error ("%s terminated with signal %d %s",
1697                  prog,
1698                  sig,
1699                  (status & 0200) ? ", core dumped" : "");
1700 #else
1701           error ("%s terminated with signal %d [%s]%s",
1702                  prog,
1703                  sig,
1704                  sys_siglist[sig],
1705                  (status & 0200) ? ", core dumped" : "");
1706 #endif
1707
1708           collect_exit (FATAL_EXIT_CODE);
1709         }
1710
1711       if (WIFEXITED (status))
1712         return WEXITSTATUS (status);
1713     }
1714   return 0;
1715 }
1716
1717 static void
1718 do_wait (prog)
1719      char *prog;
1720 {
1721   int ret = collect_wait (prog);
1722   if (ret != 0)
1723     {
1724       error ("%s returned %d exit status", prog, ret);
1725       collect_exit (ret);
1726     }
1727 }
1728
1729 \f
1730 /* Fork and execute a program, and wait for the reply.  */
1731
1732 void
1733 collect_execute (prog, argv, redir)
1734      char *prog;
1735      char **argv;
1736      char *redir;
1737 {
1738   int pid;
1739
1740   if (vflag || debug)
1741     {
1742       char **p_argv;
1743       char *str;
1744
1745       if (argv[0])
1746         fprintf (stderr, "%s", argv[0]);
1747       else
1748         fprintf (stderr, "[cannot find %s]", prog);
1749
1750       for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1751         fprintf (stderr, " %s", str);
1752
1753       fprintf (stderr, "\n");
1754     }
1755
1756   fflush (stdout);
1757   fflush (stderr);
1758
1759   /* If we cannot find a program we need, complain error.  Do this here
1760      since we might not end up needing something that we could not find.  */
1761
1762   if (argv[0] == 0)
1763     fatal ("cannot find `%s'", prog);
1764
1765   pid = vfork ();
1766   if (pid == -1)
1767     {
1768 #ifdef vfork
1769       fatal_perror ("fork");
1770 #else
1771       fatal_perror ("vfork");
1772 #endif
1773     }
1774
1775   if (pid == 0)                 /* child context */
1776     {
1777       if (redir)
1778         {
1779           unlink (redir);
1780           if (freopen (redir, "a", stdout) == NULL)
1781             fatal_perror ("redirecting stdout: %s", redir);
1782           if (freopen (redir, "a", stderr) == NULL)
1783             fatal_perror ("redirecting stderr: %s", redir);
1784         }
1785
1786       execvp (argv[0], argv);
1787       fatal_perror ("executing %s", prog);
1788     }
1789 }
1790
1791 static void
1792 fork_execute (prog, argv)
1793      char *prog;
1794      char **argv;
1795 {
1796   collect_execute (prog, argv, NULL);
1797   do_wait (prog);
1798 }
1799 \f
1800 /* Unlink a file unless we are debugging.  */
1801
1802 static void
1803 maybe_unlink (file)
1804      char *file;
1805 {
1806   if (!debug)
1807     unlink (file);
1808   else
1809     fprintf (stderr, "[Leaving %s]\n", file);
1810 }
1811
1812 \f
1813 /* Add a name to a linked list.  */
1814
1815 static void
1816 add_to_list (head_ptr, name)
1817      struct head *head_ptr;
1818      char *name;
1819 {
1820   struct id *newid
1821     = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1822   struct id *p;
1823   static long sequence_number = 0;
1824   strcpy (newid->name, name);
1825
1826   if (head_ptr->first)
1827     head_ptr->last->next = newid;
1828   else
1829     head_ptr->first = newid;
1830
1831   /* Check for duplicate symbols.  */
1832   for (p = head_ptr->first;
1833        strcmp (name, p->name) != 0;
1834        p = p->next)
1835     ;
1836   if (p != newid)
1837     {
1838       head_ptr->last->next = 0;
1839       free (newid);
1840       return;
1841     }
1842
1843   newid->sequence = ++sequence_number;
1844   head_ptr->last = newid;
1845   head_ptr->number++;
1846 }
1847
1848 /* Write: `prefix', the names on list LIST, `suffix'.  */
1849
1850 static void
1851 write_list (stream, prefix, list)
1852      FILE *stream;
1853      char *prefix;
1854      struct id *list;
1855 {
1856   while (list)
1857     {
1858       fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1859       list = list->next;
1860     }
1861 }
1862
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;
1868 {
1869   while (list)
1870     {
1871       if (!strcmp (prefix, list->name)) return 1;
1872       list = list->next;
1873     }
1874     return 0;
1875 }
1876
1877 /* Added for debugging purpose.  */
1878 static void
1879 dump_list (stream, prefix, list)
1880      FILE *stream;
1881      char *prefix;
1882      struct id *list;
1883 {
1884   while (list)
1885     {
1886       fprintf (stream, "%s%s,\n", prefix, list->name);
1887       list = list->next;
1888     }
1889 }
1890
1891 static void
1892 dump_prefix_list (stream, prefix, list)
1893      FILE *stream;
1894      char *prefix;
1895      struct prefix_list *list;
1896 {
1897   while (list)
1898     {
1899       fprintf (stream, "%s%s,\n", prefix, list->prefix);
1900       list = list->next;
1901     }
1902 }
1903
1904 static void
1905 write_list_with_asm (stream, prefix, list)
1906      FILE *stream;
1907      char *prefix;
1908      struct id *list;
1909 {
1910   while (list)
1911     {
1912       fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1913                prefix, list->sequence, list->name);
1914       list = list->next;
1915     }
1916 }
1917
1918 /* Write out the constructor and destructor tables statically (for a shared
1919    object), along with the functions to execute them.  */
1920
1921 static void
1922 write_c_file_stat (stream, name)
1923      FILE *stream;
1924      char *name;
1925 {
1926   char *prefix, *p, *q;
1927   int frames = (frame_tables.number > 0);
1928
1929   /* Figure out name of output_file, stripping off .so version.  */
1930   p = rindex (output_file, '/');
1931   if (p == 0)
1932     p = (char *) output_file;
1933   else
1934     p++;
1935   q = p;
1936   while (q)
1937     {
1938       q = index (q,'.');
1939       if (q == 0)
1940         {
1941           q = p + strlen (p);
1942           break;
1943         }
1944       else
1945         {
1946           if (strncmp (q, ".so", 3) == 0)
1947             {
1948               q += 3;
1949               break;
1950             }
1951           else
1952             q++;
1953         }
1954     }
1955   /* q points to null at end of the string (or . of the .so version) */
1956   prefix = xmalloc (q - p + 1);
1957   strncpy (prefix, p, q - p);
1958   prefix[q - p] = 0;
1959   for (q = prefix; *q; q++)
1960     if (!isalnum (*q))
1961       *q = '_';
1962   if (debug)
1963     fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1964              output_file, prefix);
1965
1966 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1967   initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1968   sprintf (initname, INIT_NAME_FORMAT, prefix);
1969
1970 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1971   fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1972   sprintf (fininame, FINI_NAME_FORMAT, prefix);
1973
1974   free (prefix);
1975
1976   /* Write the tables as C code  */
1977
1978   fprintf (stream, "static int count;\n");
1979   fprintf (stream, "typedef void entry_pt();\n");
1980   write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1981
1982   if (frames)
1983     {
1984       write_list_with_asm (stream, "extern void *", frame_tables.first);
1985
1986       fprintf (stream, "\tstatic void *frame_table[] = {\n");
1987       write_list (stream, "\t\t&", frame_tables.first);
1988       fprintf (stream, "\t0\n};\n");
1989
1990       /* This must match what's in frame.h.  */
1991       fprintf (stream, "struct object {\n");
1992       fprintf (stream, "  void *pc_begin;\n");
1993       fprintf (stream, "  void *pc_end;\n");
1994       fprintf (stream, "  void *fde_begin;\n");
1995       fprintf (stream, "  void *fde_array;\n");
1996       fprintf (stream, "  __SIZE_TYPE__ count;\n");
1997       fprintf (stream, "  struct object *next;\n");
1998       fprintf (stream, "};\n");
1999
2000       fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2001       fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2002
2003       fprintf (stream, "static void reg_frame () {\n");
2004       fprintf (stream, "\tstatic struct object ob;\n");
2005       fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2006       fprintf (stream, "\t}\n");
2007
2008       fprintf (stream, "static void dereg_frame () {\n");
2009       fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2010       fprintf (stream, "\t}\n");
2011     }
2012
2013   fprintf (stream, "void %s() {\n", initname);
2014   if (constructors.number > 0 || frames)
2015     {
2016       fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2017       write_list (stream, "\t\t", constructors.first);
2018       if (frames)
2019         fprintf (stream, "\treg_frame,\n");
2020       fprintf (stream, "\t};\n");
2021       fprintf (stream, "\tentry_pt **p;\n");
2022       fprintf (stream, "\tif (count++ != 0) return;\n");
2023       fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2024       fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2025     }
2026   else
2027     fprintf (stream, "\t++count;\n");
2028   fprintf (stream, "}\n");
2029   write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2030   fprintf (stream, "void %s() {\n", fininame);
2031   if (destructors.number > 0 || frames)
2032     {
2033       fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2034       write_list (stream, "\t\t", destructors.first);
2035       if (frames)
2036         fprintf (stream, "\tdereg_frame,\n");
2037       fprintf (stream, "\t};\n");
2038       fprintf (stream, "\tentry_pt **p;\n");
2039       fprintf (stream, "\tif (--count != 0) return;\n");
2040       fprintf (stream, "\tp = dtors;\n");
2041       fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2042                destructors.number + frames);
2043     }
2044   fprintf (stream, "}\n");
2045
2046   if (shared_obj)
2047     {
2048       fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
2049       fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
2050     }
2051 }
2052
2053 /* Write the constructor/destructor tables.  */
2054
2055 static void
2056 write_c_file_glob (stream, name)
2057      FILE *stream;
2058      char *name;
2059 {
2060   /* Write the tables as C code  */
2061
2062   int frames = (frame_tables.number > 0);
2063
2064   fprintf (stream, "typedef void entry_pt();\n\n");
2065     
2066   write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2067
2068   if (frames)
2069     {
2070       write_list_with_asm (stream, "extern void *", frame_tables.first);
2071
2072       fprintf (stream, "\tstatic void *frame_table[] = {\n");
2073       write_list (stream, "\t\t&", frame_tables.first);
2074       fprintf (stream, "\t0\n};\n");
2075
2076       /* This must match what's in frame.h.  */
2077       fprintf (stream, "struct object {\n");
2078       fprintf (stream, "  void *pc_begin;\n");
2079       fprintf (stream, "  void *pc_end;\n");
2080       fprintf (stream, "  void *fde_begin;\n");
2081       fprintf (stream, "  void *fde_array;\n");
2082       fprintf (stream, "  __SIZE_TYPE__ count;\n");
2083       fprintf (stream, "  struct object *next;\n");
2084       fprintf (stream, "};\n");
2085
2086       fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2087       fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2088
2089       fprintf (stream, "static void reg_frame () {\n");
2090       fprintf (stream, "\tstatic struct object ob;\n");
2091       fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2092       fprintf (stream, "\t}\n");
2093
2094       fprintf (stream, "static void dereg_frame () {\n");
2095       fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2096       fprintf (stream, "\t}\n");
2097     }
2098
2099   fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2100   fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2101   write_list (stream, "\t", constructors.first);
2102   if (frames)
2103     fprintf (stream, "\treg_frame,\n");
2104   fprintf (stream, "\t0\n};\n\n");
2105
2106   write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2107
2108   fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2109   fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2110   write_list (stream, "\t", destructors.first);
2111   if (frames)
2112     fprintf (stream, "\tdereg_frame,\n");
2113   fprintf (stream, "\t0\n};\n\n");
2114
2115   fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2116   fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2117 }
2118
2119 static void
2120 write_c_file (stream, name)
2121      FILE *stream;
2122      char *name;
2123 {
2124   fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2125 #ifndef LD_INIT_SWITCH
2126   if (! shared_obj)
2127     write_c_file_glob (stream, name);
2128   else
2129 #endif
2130     write_c_file_stat (stream, name);
2131   fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2132 }
2133
2134 #ifdef COLLECT_EXPORT_LIST
2135 static void
2136 write_export_file (stream)
2137      FILE *stream;
2138 {
2139   struct id *list = exports.first;
2140   for (; list; list = list->next)
2141     fprintf (stream, "%s\n", list->name);
2142 }
2143
2144 static void
2145 write_import_file (stream)
2146      FILE *stream;
2147 {
2148   struct id *list = imports.first;
2149   fprintf (stream, "%s\n", "#! .");
2150   for (; list; list = list->next)
2151     fprintf (stream, "%s\n", list->name);
2152 }
2153 #endif
2154 \f
2155 #ifdef OBJECT_FORMAT_NONE
2156
2157 /* Generic version to scan the name list of the loaded program for
2158    the symbols g++ uses for static constructors and destructors.
2159
2160    The constructor table begins at __CTOR_LIST__ and contains a count
2161    of the number of pointers (or -1 if the constructors are built in a
2162    separate section by the linker), followed by the pointers to the
2163    constructor functions, terminated with a null pointer.  The
2164    destructor table has the same format, and begins at __DTOR_LIST__.  */
2165
2166 static void
2167 scan_prog_file (prog_name, which_pass)
2168      char *prog_name;
2169      enum pass which_pass;
2170 {
2171   void (*int_handler) ();
2172   void (*quit_handler) ();
2173   char *nm_argv[4];
2174   int pid;
2175   int argc = 0;
2176   int pipe_fd[2];
2177   char *p, buf[1024];
2178   FILE *inf;
2179
2180   if (which_pass == PASS_SECOND)
2181     return;
2182
2183   /* If we do not have an `nm', complain.  */
2184   if (nm_file_name == 0)
2185     fatal ("cannot find `nm'");
2186
2187   nm_argv[argc++] = nm_file_name;
2188   if (NM_FLAGS[0] != '\0')
2189     nm_argv[argc++] = NM_FLAGS;
2190
2191   nm_argv[argc++] = prog_name;
2192   nm_argv[argc++] = (char *) 0;
2193
2194   if (pipe (pipe_fd) < 0)
2195     fatal_perror ("pipe");
2196
2197   inf = fdopen (pipe_fd[0], "r");
2198   if (inf == (FILE *) 0)
2199     fatal_perror ("fdopen");
2200
2201   /* Trace if needed.  */
2202   if (vflag)
2203     {
2204       char **p_argv;
2205       char *str;
2206
2207       for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2208         fprintf (stderr, " %s", str);
2209
2210       fprintf (stderr, "\n");
2211     }
2212
2213   fflush (stdout);
2214   fflush (stderr);
2215
2216   /* Spawn child nm on pipe */
2217   pid = vfork ();
2218   if (pid == -1)
2219     {
2220 #ifdef vfork
2221       fatal_perror ("fork");
2222 #else
2223       fatal_perror ("vfork");
2224 #endif
2225     }
2226
2227   if (pid == 0)                 /* child context */
2228     {
2229       /* setup stdout */
2230       if (dup2 (pipe_fd[1], 1) < 0)
2231         fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2232
2233       if (close (pipe_fd[0]) < 0)
2234         fatal_perror ("close (%d)", pipe_fd[0]);
2235
2236       if (close (pipe_fd[1]) < 0)
2237         fatal_perror ("close (%d)", pipe_fd[1]);
2238
2239       execv (nm_file_name, nm_argv);
2240       fatal_perror ("executing %s", nm_file_name);
2241     }
2242
2243   /* Parent context from here on.  */
2244   int_handler  = (void (*) ())signal (SIGINT,  SIG_IGN);
2245 #ifdef SIGQUIT
2246   quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2247 #endif
2248
2249   if (close (pipe_fd[1]) < 0)
2250     fatal_perror ("close (%d)", pipe_fd[1]);
2251
2252   if (debug)
2253     fprintf (stderr, "\nnm output with constructors/destructors.\n");
2254
2255   /* Read each line of nm output.  */
2256   while (fgets (buf, sizeof buf, inf) != (char *) 0)
2257     {
2258       int ch, ch2;
2259       char *name, *end;
2260
2261       /* If it contains a constructor or destructor name, add the name
2262          to the appropriate list.  */
2263
2264       for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2265         if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2266           break;
2267
2268       if (ch != '_')
2269         continue;
2270   
2271       name = p;
2272       /* Find the end of the symbol name.
2273          Do not include `|', because Encore nm can tack that on the end.  */
2274       for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
2275            end++)
2276         continue;
2277
2278
2279       *end = '\0';
2280       switch (is_ctor_dtor (name))
2281         {
2282         case 1:
2283           if (which_pass != PASS_LIB)
2284             add_to_list (&constructors, name);
2285           break;
2286
2287         case 2:
2288           if (which_pass != PASS_LIB)
2289             add_to_list (&destructors, name);
2290           break;
2291
2292         case 3:
2293           if (which_pass != PASS_LIB)
2294             fatal ("init function found in object %s", prog_name);
2295 #ifndef LD_INIT_SWITCH
2296           add_to_list (&constructors, name);
2297 #endif
2298           break;
2299
2300         case 4:
2301           if (which_pass != PASS_LIB)
2302             fatal ("fini function found in object %s", prog_name);
2303 #ifndef LD_FINI_SWITCH
2304           add_to_list (&destructors, name);
2305 #endif
2306           break;
2307
2308         case 5:
2309           if (which_pass != PASS_LIB)
2310             add_to_list (&frame_tables, name);
2311
2312         default:                /* not a constructor or destructor */
2313           continue;
2314         }
2315
2316       if (debug)
2317         fprintf (stderr, "\t%s\n", buf);
2318     }
2319
2320   if (debug)
2321     fprintf (stderr, "\n");
2322
2323   if (fclose (inf) != 0)
2324     fatal_perror ("fclose of pipe");
2325
2326   do_wait (nm_file_name);
2327
2328   signal (SIGINT,  int_handler);
2329 #ifdef SIGQUIT
2330   signal (SIGQUIT, quit_handler);
2331 #endif
2332 }
2333
2334 #if SUNOS4_SHARED_LIBRARIES
2335
2336 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2337    that the output file depends upon and their initialization/finalization
2338    routines, if any.  */
2339
2340 #include <a.out.h>
2341 #include <fcntl.h>
2342 #include <link.h>
2343 #include <sys/mman.h>
2344 #include <sys/param.h>
2345 #include <unistd.h>
2346 #include <sys/dir.h>
2347
2348 /* pointers to the object file */
2349 unsigned object;        /* address of memory mapped file */
2350 unsigned objsize;       /* size of memory mapped to file */
2351 char * code;            /* pointer to code segment */
2352 char * data;            /* pointer to data segment */
2353 struct nlist *symtab;   /* pointer to symbol table */
2354 struct link_dynamic *ld;
2355 struct link_dynamic_2 *ld_2;
2356 struct head libraries;
2357
2358 /* Map the file indicated by NAME into memory and store its address.  */
2359
2360 static void
2361 mapfile (name)
2362      char *name;
2363 {
2364   int fp;
2365   struct stat s;
2366   if ((fp = open (name, O_RDONLY)) == -1)
2367     fatal ("unable to open file '%s'", name);
2368   if (fstat (fp, &s) == -1)
2369     fatal ("unable to stat file '%s'", name);
2370
2371   objsize = s.st_size;
2372   object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2373                             fp, 0);
2374   if (object == -1)
2375     fatal ("unable to mmap file '%s'", name);
2376
2377   close (fp);
2378 }
2379
2380 /* Helpers for locatelib.  */
2381
2382 static char *libname;
2383
2384 static int
2385 libselect (d)
2386      struct direct *d;
2387 {
2388   return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2389 }
2390
2391 /* If one file has an additional numeric extension past LIBNAME, then put
2392    that one first in the sort.  If both files have additional numeric
2393    extensions, then put the one with the higher number first in the sort.
2394
2395    We must verify that the extension is numeric, because Sun saves the
2396    original versions of patched libraries with a .FCS extension.  Files with
2397    invalid extensions must go last in the sort, so that they will not be used.  */
2398
2399 static int
2400 libcompare (d1, d2)
2401      struct direct **d1, **d2;
2402 {
2403   int i1, i2 = strlen (libname);
2404   char *e1 = (*d1)->d_name + i2;
2405   char *e2 = (*d2)->d_name + i2;
2406
2407   while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2408          && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2409     {
2410       ++e1;
2411       ++e2;
2412       i1 = strtol (e1, &e1, 10);
2413       i2 = strtol (e2, &e2, 10);
2414       if (i1 != i2)
2415         return i1 - i2;
2416     }
2417
2418   if (*e1)
2419     {
2420       /* It has a valid numeric extension, prefer this one.  */
2421       if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2422         return 1;
2423       /* It has a invalid numeric extension, must prefer the other one.  */
2424       else
2425         return -1;
2426     }
2427   else if (*e2)
2428     {
2429       /* It has a valid numeric extension, prefer this one.  */
2430       if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2431         return -1;
2432       /* It has a invalid numeric extension, must prefer the other one.  */
2433       else
2434         return 1;
2435     }
2436   else
2437     return 0;
2438 }
2439
2440 /* Given the name NAME of a dynamic dependency, find its pathname and add
2441    it to the list of libraries.  */
2442
2443 static void
2444 locatelib (name)
2445      char *name;
2446 {
2447   static char **l;
2448   static int cnt;
2449   char buf[MAXPATHLEN];
2450   char *p, *q;
2451   char **pp;
2452
2453   if (l == 0)
2454     {
2455       char *ld_rules;
2456       char *ldr = 0;
2457       /* counting elements in array, need 1 extra for null */
2458       cnt = 1;  
2459       ld_rules = (char *) (ld_2->ld_rules + code);
2460       if (ld_rules)
2461         {
2462           cnt++;
2463           for (; *ld_rules != 0; ld_rules++)
2464             if (*ld_rules == ':')
2465               cnt++;
2466           ld_rules = (char *) (ld_2->ld_rules + code);
2467           ldr = (char *) malloc (strlen (ld_rules) + 1);
2468           strcpy (ldr, ld_rules);
2469         }
2470       p = getenv ("LD_LIBRARY_PATH");
2471       q = 0;
2472       if (p)
2473         {
2474           cnt++;
2475           for (q = p ; *q != 0; q++)
2476             if (*q == ':')
2477               cnt++;
2478           q = (char *) malloc (strlen (p) + 1);
2479           strcpy (q, p);
2480         }
2481       l = (char **) malloc ((cnt + 3) * sizeof (char *));
2482       pp = l;
2483       if (ldr)
2484         {
2485           *pp++ = ldr;
2486           for (; *ldr != 0; ldr++) 
2487             if (*ldr == ':')
2488               {
2489                 *ldr++ = 0;
2490                 *pp++ = ldr;
2491               }
2492         }
2493       if (q)
2494         {
2495           *pp++ = q;
2496           for (; *q != 0; q++) 
2497             if (*q == ':')
2498               {
2499                 *q++ = 0;
2500                 *pp++ = q;
2501               }
2502         }
2503       /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2504       *pp++ = "/lib";
2505       *pp++ = "/usr/lib";
2506       *pp++ = "/usr/local/lib";
2507       *pp = 0;
2508     }
2509   libname = name;
2510   for (pp = l; *pp != 0 ; pp++)
2511     {
2512       struct direct **namelist;
2513       int entries;
2514       if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2515         {
2516           sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2517           add_to_list (&libraries, buf);
2518           if (debug)
2519             fprintf (stderr, "%s\n", buf);
2520           break;
2521         }
2522     }
2523   if (*pp == 0)
2524     {
2525       if (debug)
2526         fprintf (stderr, "not found\n");
2527       else
2528         fatal ("dynamic dependency %s not found", name);
2529     }
2530 }
2531
2532 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2533    that it depends upon and any constructors or destructors they contain.  */
2534
2535 static void 
2536 scan_libraries (prog_name)
2537      char *prog_name;
2538 {
2539   struct exec *header;
2540   char *base;
2541   struct link_object *lo;
2542   char buff[MAXPATHLEN];
2543   struct id *list;
2544
2545   mapfile (prog_name);
2546   header = (struct exec *)object;
2547   if (N_BADMAG (*header))
2548     fatal ("bad magic number in file '%s'", prog_name);
2549   if (header->a_dynamic == 0)
2550     return;
2551
2552   code = (char *) (N_TXTOFF (*header) + (long) header);
2553   data = (char *) (N_DATOFF (*header) + (long) header);
2554   symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2555
2556   if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2557     {
2558       /* shared object */
2559       ld = (struct link_dynamic *) (symtab->n_value + code);
2560       base = code;
2561     }
2562   else
2563     {
2564       /* executable */
2565       ld = (struct link_dynamic *) data;
2566       base = code-PAGSIZ;
2567     }
2568
2569   if (debug)
2570     fprintf (stderr, "dynamic dependencies.\n");
2571
2572   ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2573   for (lo = (struct link_object *) ld_2->ld_need; lo;
2574        lo = (struct link_object *) lo->lo_next)
2575     {
2576       char *name;
2577       lo = (struct link_object *) ((long) lo + code);
2578       name = (char *) (code + lo->lo_name);
2579       if (lo->lo_library)
2580         {
2581           if (debug)
2582             fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2583           sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2584           locatelib (buff);
2585         }
2586       else
2587         {
2588           if (debug)
2589             fprintf (stderr, "\t%s\n", name);
2590           add_to_list (&libraries, name);
2591         }
2592     }
2593
2594   if (debug)
2595     fprintf (stderr, "\n");
2596
2597   /* now iterate through the library list adding their symbols to
2598      the list.  */
2599   for (list = libraries.first; list; list = list->next)
2600     scan_prog_file (list->name, PASS_LIB);
2601 }
2602
2603 #else  /* SUNOS4_SHARED_LIBRARIES */
2604 #ifdef LDD_SUFFIX
2605
2606 /* Use the List Dynamic Dependencies program to find shared libraries that
2607    the output file depends upon and their initialization/finalization
2608    routines, if any.  */
2609
2610 static void 
2611 scan_libraries (prog_name)
2612      char *prog_name;
2613 {
2614   static struct head libraries;         /* list of shared libraries found */
2615   struct id *list;
2616   void (*int_handler) ();
2617   void (*quit_handler) ();
2618   char *ldd_argv[4];
2619   int pid;
2620   int argc = 0;
2621   int pipe_fd[2];
2622   char buf[1024];
2623   FILE *inf;
2624
2625   /* If we do not have an `ldd', complain.  */
2626   if (ldd_file_name == 0)
2627     {
2628       error ("cannot find `ldd'");
2629       return;
2630     }
2631
2632   ldd_argv[argc++] = ldd_file_name;
2633   ldd_argv[argc++] = prog_name;
2634   ldd_argv[argc++] = (char *) 0;
2635
2636   if (pipe (pipe_fd) < 0)
2637     fatal_perror ("pipe");
2638
2639   inf = fdopen (pipe_fd[0], "r");
2640   if (inf == (FILE *) 0)
2641     fatal_perror ("fdopen");
2642
2643   /* Trace if needed.  */
2644   if (vflag)
2645     {
2646       char **p_argv;
2647       char *str;
2648
2649       for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2650         fprintf (stderr, " %s", str);
2651
2652       fprintf (stderr, "\n");
2653     }
2654
2655   fflush (stdout);
2656   fflush (stderr);
2657
2658   /* Spawn child ldd on pipe */
2659   pid = vfork ();
2660   if (pid == -1)
2661     {
2662 #ifdef vfork
2663       fatal_perror ("fork");
2664 #else
2665       fatal_perror ("vfork");
2666 #endif
2667     }
2668
2669   if (pid == 0)                 /* child context */
2670     {
2671       /* setup stdout */
2672       if (dup2 (pipe_fd[1], 1) < 0)
2673         fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2674
2675       if (close (pipe_fd[0]) < 0)
2676         fatal_perror ("close (%d)", pipe_fd[0]);
2677
2678       if (close (pipe_fd[1]) < 0)
2679         fatal_perror ("close (%d)", pipe_fd[1]);
2680
2681       execv (ldd_file_name, ldd_argv);
2682       fatal_perror ("executing %s", ldd_file_name);
2683     }
2684
2685   /* Parent context from here on.  */
2686   int_handler  = (void (*) ()) signal (SIGINT,  SIG_IGN);
2687 #ifdef SIGQUIT
2688   quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2689 #endif
2690
2691   if (close (pipe_fd[1]) < 0)
2692     fatal_perror ("close (%d)", pipe_fd[1]);
2693
2694   if (debug)
2695     fprintf (stderr, "\nldd output with constructors/destructors.\n");
2696
2697   /* Read each line of ldd output.  */
2698   while (fgets (buf, sizeof buf, inf) != (char *) 0)
2699     {
2700       int ch, ch2;
2701       char *name, *end, *p = buf;
2702
2703       /* Extract names of libraries and add to list.  */
2704       PARSE_LDD_OUTPUT (p);
2705       if (p == 0)
2706         continue;
2707
2708       name = p;
2709       if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2710         fatal ("dynamic dependency %s not found", buf);
2711
2712       /* Find the end of the symbol name.  */
2713       for (end = p; 
2714            (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2715            end++)
2716         continue;
2717       *end = '\0';
2718
2719       if (access (name, R_OK) == 0)
2720         add_to_list (&libraries, name);
2721       else
2722         fatal ("unable to open dynamic dependency '%s'", buf);
2723
2724       if (debug)
2725         fprintf (stderr, "\t%s\n", buf);
2726     }
2727   if (debug)
2728     fprintf (stderr, "\n");
2729
2730   if (fclose (inf) != 0)
2731     fatal_perror ("fclose of pipe");
2732
2733   do_wait (ldd_file_name);
2734
2735   signal (SIGINT,  int_handler);
2736 #ifdef SIGQUIT
2737   signal (SIGQUIT, quit_handler);
2738 #endif
2739
2740   /* now iterate through the library list adding their symbols to
2741      the list.  */
2742   for (list = libraries.first; list; list = list->next)
2743     scan_prog_file (list->name, PASS_LIB);
2744 }
2745
2746 #endif /* LDD_SUFFIX */
2747 #endif /* SUNOS4_SHARED_LIBRARIES */
2748
2749 #endif /* OBJECT_FORMAT_NONE */
2750
2751 \f
2752 /*
2753  * COFF specific stuff.
2754  */
2755
2756 #ifdef OBJECT_FORMAT_COFF
2757
2758 #if defined(EXTENDED_COFF)
2759 #   define GCC_SYMBOLS(X)       (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2760 #   define GCC_SYMENT           SYMR
2761 #   define GCC_OK_SYMBOL(X)     ((X).st == stProc && (X).sc == scText)
2762 #   define GCC_SYMINC(X)        (1)
2763 #   define GCC_SYMZERO(X)       (SYMHEADER(X).isymMax)
2764 #   define GCC_CHECK_HDR(X)     (PSYMTAB(X) != 0)
2765 #else
2766 #   define GCC_SYMBOLS(X)       (HEADER(ldptr).f_nsyms)
2767 #   define GCC_SYMENT           SYMENT
2768 #   define GCC_OK_SYMBOL(X) \
2769      (((X).n_sclass == C_EXT) && \
2770       ((X).n_scnum > N_UNDEF) && \
2771       (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2772        ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2773 #   define GCC_UNDEF_SYMBOL(X) \
2774      (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2775 #   define GCC_SYMINC(X)        ((X).n_numaux+1)
2776 #   define GCC_SYMZERO(X)       0
2777 #   define GCC_CHECK_HDR(X)     (1)
2778 #endif
2779
2780 extern char *ldgetname ();
2781
2782 /* COFF version to scan the name list of the loaded program for
2783    the symbols g++ uses for static constructors and destructors.
2784
2785    The constructor table begins at __CTOR_LIST__ and contains a count
2786    of the number of pointers (or -1 if the constructors are built in a
2787    separate section by the linker), followed by the pointers to the
2788    constructor functions, terminated with a null pointer.  The
2789    destructor table has the same format, and begins at __DTOR_LIST__.  */
2790
2791 static void
2792 scan_prog_file (prog_name, which_pass)
2793      char *prog_name;
2794      enum pass which_pass;
2795 {
2796   LDFILE *ldptr = NULL;
2797   int sym_index, sym_count;
2798   int is_shared = 0;
2799 #ifdef COLLECT_EXPORT_LIST
2800   /* Should we generate an import list for given prog_name?  */
2801   int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2802 #endif
2803
2804   if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2805     return;
2806
2807 #ifdef COLLECT_EXPORT_LIST
2808   /* We do not need scanning for some standard C libraries.  */
2809   if (which_pass == PASS_FIRST && ignore_library (prog_name))
2810     return;
2811
2812   /* On AIX we have a loop, because there is not much difference
2813      between an object and an archive. This trick allows us to
2814      eliminate scan_libraries() function.  */
2815   do
2816     {
2817 #endif
2818       if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
2819         {
2820
2821           if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2822             fatal ("%s: not a COFF file", prog_name);
2823
2824 #ifdef COLLECT_EXPORT_LIST
2825           /* Is current archive member a shared object?  */
2826           is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2827 #endif
2828           if (GCC_CHECK_HDR (ldptr))
2829             {
2830               sym_count = GCC_SYMBOLS (ldptr);
2831               sym_index = GCC_SYMZERO (ldptr);
2832               while (sym_index < sym_count)
2833                 {
2834                   GCC_SYMENT symbol;
2835
2836                   if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2837                     break;
2838                   sym_index += GCC_SYMINC (symbol);
2839
2840                   if (GCC_OK_SYMBOL (symbol))
2841                     {
2842                       char *name;
2843
2844                       if ((name = ldgetname (ldptr, &symbol)) == NULL)
2845                         continue;               /* should never happen */
2846
2847 #ifdef XCOFF_DEBUGGING_INFO
2848                       /* All AIX function names have a duplicate entry
2849                          beginning with a dot.  */
2850                       if (*name == '.')
2851                         ++name;
2852 #endif
2853
2854                       switch (is_ctor_dtor (name))
2855                         {
2856                         case 1:
2857                           if (! is_shared) add_to_list (&constructors, name);
2858                           if (which_pass == PASS_OBJ)
2859                             add_to_list (&exports, name);
2860 #ifdef COLLECT_EXPORT_LIST
2861                           /* If this symbol was undefined and we are building
2862                              an import list, we should add a symbol to this
2863                              list.  */
2864                           else
2865                             if (import_flag
2866                                 && is_in_list (name, undefined.first))
2867                               add_to_list (&imports, name);
2868 #endif
2869                           break;
2870
2871                         case 2:
2872                           if (! is_shared) add_to_list (&destructors, name);
2873                           if (which_pass == PASS_OBJ)
2874                             add_to_list (&exports, name);
2875 #ifdef COLLECT_EXPORT_LIST
2876                           /* If this symbol was undefined and we are building
2877                              an import list, we should add a symbol to this
2878                              list.  */
2879                           else
2880                             if (import_flag
2881                                 && is_in_list (name, undefined.first))
2882                               add_to_list (&imports, name);
2883 #endif
2884                           break;
2885
2886 #ifdef COLLECT_EXPORT_LIST
2887                         case 3:
2888                           if (is_shared)
2889                             add_to_list (&constructors, name);
2890                           break;
2891
2892                         case 4:
2893                           if (is_shared)
2894                             add_to_list (&destructors, name);
2895                           break;
2896 #endif
2897
2898                         default:        /* not a constructor or destructor */
2899 #ifdef COLLECT_EXPORT_LIST
2900                           /* If we are building a shared object on AIX we need
2901                              to explicitly export all global symbols or add
2902                              them to import list.  */
2903                           if (shared_obj) 
2904                             if (which_pass == PASS_OBJ && (! export_flag))
2905                               add_to_list (&exports, name);
2906                             else if (! is_shared && which_pass == PASS_FIRST
2907                                      && import_flag
2908                                      && is_in_list(name, undefined.first))
2909                               add_to_list (&imports, name);
2910 #endif
2911                           continue;
2912                         }
2913
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 = %5d, index = %5d, name = %s\n",
2924                                  symbol.iss, symbol.value, symbol.index, name);
2925 #endif
2926                     }
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))
2932                     {
2933                       char *name;
2934
2935                       if ((name = ldgetname (ldptr, &symbol)) == NULL)
2936                         continue;               /* should never happen */
2937
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);
2943                     }
2944 #endif
2945                 }
2946             }
2947         }
2948       else
2949         {
2950           fatal ("%s: cannot open as COFF file", prog_name);
2951         }
2952 #ifdef COLLECT_EXPORT_LIST
2953       /* On AIX loop continues while there are more members in archive.  */
2954     }
2955   while (ldclose (ldptr) == FAILURE);
2956 #else
2957   /* Otherwise we simply close ldptr.  */
2958   (void) ldclose(ldptr);
2959 #endif
2960 }
2961
2962
2963 #ifdef COLLECT_EXPORT_LIST
2964
2965 /* This new function is used to decide whether we should
2966    generate import list for an object or to use it directly.  */
2967 static int
2968 use_import_list (prog_name)
2969      char *prog_name;
2970 {
2971   char *p;
2972
2973   /* If we do not build a shared object then import list should not be used.  */
2974   if (! shared_obj) return 0;
2975
2976   /* Currently we check only for libgcc, but this can be changed in future.  */
2977   p = strstr (prog_name, "libgcc.a");
2978   if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
2979     return 1;
2980   return 0;
2981 }
2982
2983 /* Given a library name without "lib" prefix, this function
2984    returns a full library name including a path.  */
2985 static char *
2986 resolve_lib_name (name)
2987      char *name;
2988 {
2989   char *lib_buf;
2990   int i, j, l = 0;
2991
2992   for (i = 0; libpaths[i]; i++)
2993     if (libpaths[i]->max_len > l)
2994       l = libpaths[i]->max_len;
2995
2996   lib_buf = xmalloc (l + strlen(name) + 10);
2997
2998   for (i = 0; libpaths[i]; i++)
2999     {
3000       struct prefix_list *list = libpaths[i]->plist;
3001       for (; list; list = list->next)
3002         {
3003           for (j = 0; libexts[j]; j++)
3004             {
3005               /* The following lines are needed because path_prefix list
3006                  may contain directories both with trailing '/' and
3007                  without it.  */
3008               char *p = "";
3009               if (list->prefix[strlen(list->prefix)-1] != '/')
3010                 p = "/";
3011               sprintf (lib_buf, "%s%slib%s.%s",
3012                        list->prefix, p, name, libexts[j]);
3013 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
3014               if (file_exists (lib_buf))
3015                 {
3016 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
3017                   return (lib_buf);
3018                 }
3019             }
3020         }
3021     }
3022   if (debug)
3023     fprintf (stderr, "not found\n");
3024   else
3025     fatal ("Library lib%s not found", name);
3026   return (NULL);
3027 }
3028
3029 /* Array of standard AIX libraries which should not
3030    be scanned for ctors/dtors.  */
3031 static char* aix_std_libs[] = {
3032   "/unix",
3033   "/lib/libc.a",
3034   "/lib/libc_r.a",
3035   "/usr/lib/libc.a",
3036   "/usr/lib/libc_r.a",
3037   "/usr/lib/threads/libc.a",
3038   "/usr/ccs/lib/libc.a",
3039   "/usr/ccs/lib/libc_r.a",
3040   NULL
3041 };
3042
3043 /* This function checks the filename and returns 1
3044    if this name matches the location of a standard AIX library. */
3045 static int
3046 ignore_library (name)
3047      char *name;
3048 {
3049   char **p = &aix_std_libs[0];
3050   while (*p++ != NULL)
3051     if (! strcmp (name, *p)) return 1;
3052   return 0;
3053 }
3054
3055 #endif
3056
3057 #endif /* OBJECT_FORMAT_COFF */
3058
3059 \f
3060 /*
3061  * OSF/rose specific stuff.
3062  */
3063
3064 #ifdef OBJECT_FORMAT_ROSE
3065
3066 /* Union of the various load commands */
3067
3068 typedef union load_union
3069 {
3070   ldc_header_t                  hdr;    /* common header */
3071   load_cmd_map_command_t        map;    /* map indexing other load cmds */
3072   interpreter_command_t         iprtr;  /* interpreter pathname */
3073   strings_command_t             str;    /* load commands strings section */
3074   region_command_t              region; /* region load command */
3075   reloc_command_t               reloc;  /* relocation section */
3076   package_command_t             pkg;    /* package load command */
3077   symbols_command_t             sym;    /* symbol sections */
3078   entry_command_t               ent;    /* program start section */
3079   gen_info_command_t            info;   /* object information */
3080   func_table_command_t          func;   /* function constructors/destructors */
3081 } load_union_t;
3082
3083 /* Structure to point to load command and data section in memory.  */
3084
3085 typedef struct load_all
3086 {
3087   load_union_t *load;                   /* load command */
3088   char *section;                        /* pointer to section */
3089 } load_all_t;
3090
3091 /* Structure to contain information about a file mapped into memory.  */
3092
3093 struct file_info
3094 {
3095   char *start;                          /* start of map */
3096   char *name;                           /* filename */
3097   long  size;                           /* size of the file */
3098   long  rounded_size;                   /* size rounded to page boundary */
3099   int   fd;                             /* file descriptor */
3100   int   rw;                             /* != 0 if opened read/write */
3101   int   use_mmap;                       /* != 0 if mmap'ed */
3102 };
3103
3104 extern int decode_mach_o_hdr ();
3105 extern int encode_mach_o_hdr ();
3106
3107 static void add_func_table      PROTO((mo_header_t *, load_all_t *,
3108                                        symbol_info_t *, int));
3109 static void print_header        PROTO((mo_header_t *));
3110 static void print_load_command  PROTO((load_union_t *, size_t, int));
3111 static void bad_header          PROTO((int));
3112 static struct file_info *read_file  PROTO((char *, int, int));
3113 static void end_file            PROTO((struct file_info *));
3114 \f
3115 /* OSF/rose specific version to scan the name list of the loaded
3116    program for the symbols g++ uses for static constructors and
3117    destructors.
3118
3119    The constructor table begins at __CTOR_LIST__ and contains a count
3120    of the number of pointers (or -1 if the constructors are built in a
3121    separate section by the linker), followed by the pointers to the
3122    constructor functions, terminated with a null pointer.  The
3123    destructor table has the same format, and begins at __DTOR_LIST__.  */
3124
3125 static void
3126 scan_prog_file (prog_name, which_pass)
3127      char *prog_name;
3128      enum pass which_pass;
3129 {
3130   char *obj;
3131   mo_header_t hdr;
3132   load_all_t *load_array;
3133   load_all_t *load_end;
3134   load_all_t *load_cmd;
3135   int symbol_load_cmds;
3136   off_t offset;
3137   int i;
3138   int num_syms;
3139   int status;
3140   char *str_sect;
3141   struct file_info *obj_file;
3142   int prog_fd;
3143   mo_lcid_t cmd_strings   = -1;
3144   symbol_info_t *main_sym = 0;
3145   int rw                  = (which_pass != PASS_FIRST);
3146
3147   prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3148   if (prog_fd < 0)
3149     fatal_perror ("cannot read %s", prog_name);
3150
3151   obj_file = read_file (prog_name, prog_fd, rw);
3152   obj = obj_file->start;
3153
3154   status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3155   if (status != MO_HDR_CONV_SUCCESS)
3156     bad_header (status);
3157
3158
3159   /* Do some basic sanity checks.  Note we explicitly use the big endian magic number,
3160      since the hardware will automatically swap bytes for us on loading little endian
3161      integers.  */
3162
3163 #ifndef CROSS_COMPILE
3164   if (hdr.moh_magic != MOH_MAGIC_MSB
3165       || hdr.moh_header_version != MOH_HEADER_VERSION
3166       || hdr.moh_byte_order != OUR_BYTE_ORDER
3167       || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3168       || hdr.moh_cpu_type != OUR_CPU_TYPE
3169       || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3170       || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3171     {
3172       fatal ("incompatibilities between object file & expected values");
3173     }
3174 #endif
3175
3176   if (debug)
3177     print_header (&hdr);
3178
3179   offset = hdr.moh_first_cmd_off;
3180   load_end = load_array
3181     = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3182
3183   /* Build array of load commands, calculating the offsets */
3184   for (i = 0; i < hdr.moh_n_load_cmds; i++)
3185     {
3186       load_union_t *load_hdr;           /* load command header */
3187
3188       load_cmd = load_end++;
3189       load_hdr = (load_union_t *) (obj + offset);
3190
3191       /* If modifying the program file, copy the header.  */
3192       if (rw)
3193         {
3194           load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3195           bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3196           load_hdr = ptr;
3197
3198           /* null out old command map, because we will rewrite at the end.  */
3199           if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3200             {
3201               cmd_strings = ptr->map.lcm_ld_cmd_strings;
3202               ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3203             }
3204         }
3205
3206       load_cmd->load = load_hdr;
3207       if (load_hdr->hdr.ldci_section_off > 0)
3208         load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3209
3210       if (debug)
3211         print_load_command (load_hdr, offset, i);
3212
3213       offset += load_hdr->hdr.ldci_cmd_size;
3214     }
3215
3216   /* If the last command is the load command map and is not undefined,
3217      decrement the count of load commands.  */
3218   if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3219     {
3220       load_end--;
3221       hdr.moh_n_load_cmds--;
3222     }
3223
3224   /* Go through and process each symbol table section.  */
3225   symbol_load_cmds = 0;
3226   for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3227     {
3228       load_union_t *load_hdr = load_cmd->load;
3229
3230       if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3231         {
3232           symbol_load_cmds++;
3233
3234           if (debug)
3235             {
3236               char *kind = "unknown";
3237
3238               switch (load_hdr->sym.symc_kind)
3239                 {
3240                 case SYMC_IMPORTS:         kind = "imports"; break;
3241                 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3242                 case SYMC_STABS:           kind = "stabs";   break;
3243                 }
3244
3245               fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3246                        symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3247             }
3248
3249           if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3250             continue;
3251
3252           str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3253           if (str_sect == (char *) 0)
3254             fatal ("string section missing");
3255
3256           if (load_cmd->section == (char *) 0)
3257             fatal ("section pointer missing");
3258
3259           num_syms = load_hdr->sym.symc_nentries;
3260           for (i = 0; i < num_syms; i++)
3261             {
3262               symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3263               char *name = sym->si_name.symbol_name + str_sect;
3264
3265               if (name[0] != '_')
3266                 continue;
3267
3268               if (rw)
3269                 {
3270                   char *n = name + strlen (name) - strlen (NAME__MAIN);
3271
3272                   if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3273                     continue;
3274                   while (n != name)
3275                     if (*--n != '_')
3276                       continue;
3277
3278                   main_sym = sym;
3279                 }
3280               else
3281                 {
3282                   switch (is_ctor_dtor (name))
3283                     {
3284                     case 1:
3285                       add_to_list (&constructors, name);
3286                       break;
3287
3288                     case 2:
3289                       add_to_list (&destructors, name);
3290                       break;
3291
3292                     default:    /* not a constructor or destructor */
3293                       continue;
3294                     }
3295                 }
3296
3297               if (debug)
3298                 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3299                          sym->si_type, sym->si_sc_type, sym->si_flags, name);
3300             }
3301         }
3302     }
3303
3304   if (symbol_load_cmds == 0)
3305     fatal ("no symbol table found");
3306
3307   /* Update the program file now, rewrite header and load commands.  At present,
3308      we assume that there is enough space after the last load command to insert
3309      one more.  Since the first section written out is page aligned, and the
3310      number of load commands is small, this is ok for the present.  */
3311
3312   if (rw)
3313     {
3314       load_union_t *load_map;
3315       size_t size;
3316
3317       if (cmd_strings == -1)
3318         fatal ("no cmd_strings found");
3319
3320       /* Add __main to initializer list.
3321          If we are building a program instead of a shared library, do not
3322          do anything, since in the current version, you cannot do mallocs
3323          and such in the constructors.  */
3324
3325       if (main_sym != (symbol_info_t *) 0
3326           && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3327         add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3328
3329       if (debug)
3330         fprintf (stderr, "\nUpdating header and load commands.\n\n");
3331
3332       hdr.moh_n_load_cmds++;
3333       size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3334
3335       /* Create new load command map.  */
3336       if (debug)
3337         fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3338                  (int)hdr.moh_n_load_cmds, (long)size);
3339
3340       load_map = (load_union_t *) xcalloc (1, size);
3341       load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3342       load_map->map.ldc_header.ldci_cmd_size = size;
3343       load_map->map.lcm_ld_cmd_strings = cmd_strings;
3344       load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3345       load_array[hdr.moh_n_load_cmds-1].load = load_map;
3346
3347       offset = hdr.moh_first_cmd_off;
3348       for (i = 0; i < hdr.moh_n_load_cmds; i++)
3349         {
3350           load_map->map.lcm_map[i] = offset;
3351           if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3352             hdr.moh_load_map_cmd_off = offset;
3353
3354           offset += load_array[i].load->hdr.ldci_cmd_size;
3355         }
3356
3357       hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3358
3359       if (debug)
3360         print_header (&hdr);
3361
3362       /* Write header */
3363       status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3364       if (status != MO_HDR_CONV_SUCCESS)
3365         bad_header (status);
3366
3367       if (debug)
3368         fprintf (stderr, "writing load commands.\n\n");
3369
3370       /* Write load commands */
3371       offset = hdr.moh_first_cmd_off;
3372       for (i = 0; i < hdr.moh_n_load_cmds; i++)
3373         {
3374           load_union_t *load_hdr = load_array[i].load;
3375           size_t size = load_hdr->hdr.ldci_cmd_size;
3376
3377           if (debug)
3378             print_load_command (load_hdr, offset, i);
3379
3380           bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3381           offset += size;
3382         }
3383     }
3384
3385   end_file (obj_file);
3386
3387   if (close (prog_fd))
3388     fatal_perror ("closing %s", prog_name);
3389
3390   if (debug)
3391     fprintf (stderr, "\n");
3392 }
3393
3394 \f
3395 /* Add a function table to the load commands to call a function
3396    on initiation or termination of the process.  */
3397
3398 static void
3399 add_func_table (hdr_p, load_array, sym, type)
3400      mo_header_t *hdr_p;                /* pointer to global header */
3401      load_all_t *load_array;            /* array of ptrs to load cmds */
3402      symbol_info_t *sym;                /* pointer to symbol entry */
3403      int type;                          /* fntc_type value */
3404 {
3405   /* Add a new load command.  */
3406   int num_cmds = ++hdr_p->moh_n_load_cmds;
3407   int load_index = num_cmds - 1;
3408   size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3409   load_union_t *ptr = xcalloc (1, size);
3410   load_all_t *load_cmd;
3411   int i;
3412
3413   /* Set the unresolved address bit in the header to force the loader to be
3414      used, since kernel exec does not call the initialization functions.  */
3415   hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3416
3417   load_cmd = &load_array[load_index];
3418   load_cmd->load = ptr;
3419   load_cmd->section = (char *) 0;
3420
3421   /* Fill in func table load command.  */
3422   ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3423   ptr->func.ldc_header.ldci_cmd_size = size;
3424   ptr->func.ldc_header.ldci_section_off = 0;
3425   ptr->func.ldc_header.ldci_section_len = 0;
3426   ptr->func.fntc_type = type;
3427   ptr->func.fntc_nentries = 1;
3428
3429   /* copy address, turn it from abs. address to (region,offset) if necessary.  */
3430   /* Is the symbol already expressed as (region, offset)?  */
3431   if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3432     {
3433       ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3434       ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3435     }
3436
3437   /* If not, figure out which region it's in.  */
3438   else
3439     {
3440       mo_vm_addr_t addr = sym->si_value.abs_val;
3441       int found = 0;
3442
3443       for (i = 0; i < load_index; i++)
3444         {
3445           if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3446             {
3447               region_command_t *region_ptr = &load_array[i].load->region;
3448
3449               if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3450                   && addr >= region_ptr->regc_addr.vm_addr
3451                   && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3452                 {
3453                   ptr->func.fntc_entry_loc[0].adr_lcid = i;
3454                   ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3455                   found++;
3456                   break;
3457                 }
3458             }
3459         }
3460
3461       if (!found)
3462         fatal ("could not convert 0x%l.8x into a region", addr);
3463     }
3464
3465   if (debug)
3466     fprintf (stderr,
3467              "%s function, region %d, offset = %ld (0x%.8lx)\n",
3468              (type == FNTC_INITIALIZATION) ? "init" : "term",
3469              (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3470              (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3471              (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3472
3473 }
3474
3475 \f
3476 /* Print the global header for an OSF/rose object.  */
3477
3478 static void
3479 print_header (hdr_ptr)
3480      mo_header_t *hdr_ptr;
3481 {
3482   fprintf (stderr, "\nglobal header:\n");
3483   fprintf (stderr, "\tmoh_magic            = 0x%.8lx\n", hdr_ptr->moh_magic);
3484   fprintf (stderr, "\tmoh_major_version    = %d\n", (int)hdr_ptr->moh_major_version);
3485   fprintf (stderr, "\tmoh_minor_version    = %d\n", (int)hdr_ptr->moh_minor_version);
3486   fprintf (stderr, "\tmoh_header_version   = %d\n", (int)hdr_ptr->moh_header_version);
3487   fprintf (stderr, "\tmoh_max_page_size    = %d\n", (int)hdr_ptr->moh_max_page_size);
3488   fprintf (stderr, "\tmoh_byte_order       = %d\n", (int)hdr_ptr->moh_byte_order);
3489   fprintf (stderr, "\tmoh_data_rep_id      = %d\n", (int)hdr_ptr->moh_data_rep_id);
3490   fprintf (stderr, "\tmoh_cpu_type         = %d\n", (int)hdr_ptr->moh_cpu_type);
3491   fprintf (stderr, "\tmoh_cpu_subtype      = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3492   fprintf (stderr, "\tmoh_vendor_type      = %d\n", (int)hdr_ptr->moh_vendor_type);
3493   fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3494   fprintf (stderr, "\tmoh_first_cmd_off    = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3495   fprintf (stderr, "\tmoh_sizeofcmds       = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3496   fprintf (stderr, "\tmon_n_load_cmds      = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3497   fprintf (stderr, "\tmoh_flags            = 0x%.8lx", (long)hdr_ptr->moh_flags);
3498
3499   if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3500     fprintf (stderr, ", relocatable");
3501
3502   if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3503     fprintf (stderr, ", linkable");
3504
3505   if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3506     fprintf (stderr, ", execable");
3507
3508   if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3509     fprintf (stderr, ", executable");
3510
3511   if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3512     fprintf (stderr, ", unresolved");
3513
3514   fprintf (stderr, "\n\n");
3515   return;
3516 }
3517
3518 \f
3519 /* Print a short summary of a load command.  */
3520
3521 static void
3522 print_load_command (load_hdr, offset, number)
3523      load_union_t *load_hdr;
3524      size_t offset;
3525      int number;
3526 {
3527   mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3528   char *type_str = (char *) 0;
3529
3530   switch (type)
3531     {
3532     case LDC_UNDEFINED:   type_str = "UNDEFINED";       break;
3533     case LDC_CMD_MAP:     type_str = "CMD_MAP";         break;
3534     case LDC_INTERPRETER: type_str = "INTERPRETER";     break;
3535     case LDC_STRINGS:     type_str = "STRINGS";         break;
3536     case LDC_REGION:      type_str = "REGION";          break;
3537     case LDC_RELOC:       type_str = "RELOC";           break;
3538     case LDC_PACKAGE:     type_str = "PACKAGE";         break;
3539     case LDC_SYMBOLS:     type_str = "SYMBOLS";         break;
3540     case LDC_ENTRY:       type_str = "ENTRY";           break;
3541     case LDC_FUNC_TABLE:  type_str = "FUNC_TABLE";      break;
3542     case LDC_GEN_INFO:    type_str = "GEN_INFO";        break;
3543     }
3544
3545   fprintf (stderr,
3546            "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3547            number,
3548            (long) load_hdr->hdr.ldci_cmd_size,
3549            (long) offset,
3550            (long) load_hdr->hdr.ldci_section_off,
3551            (long) load_hdr->hdr.ldci_section_len);
3552
3553   if (type_str == (char *) 0)
3554     fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3555
3556   else if (type != LDC_REGION)
3557     fprintf (stderr, ", ty: %s\n", type_str);
3558
3559   else
3560     {
3561       char *region = "";
3562       switch (load_hdr->region.regc_usage_type)
3563         {
3564         case REG_TEXT_T:        region = ", .text";     break;
3565         case REG_DATA_T:        region = ", .data";     break;
3566         case REG_BSS_T:         region = ", .bss";      break;
3567         case REG_GLUE_T:        region = ", .glue";     break;
3568 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3569         case REG_RDATA_T:       region = ", .rdata";    break;
3570         case REG_SDATA_T:       region = ", .sdata";    break;
3571         case REG_SBSS_T:        region = ", .sbss";     break;
3572 #endif
3573         }
3574
3575       fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3576                type_str,
3577                (long) load_hdr->region.regc_vm_addr,
3578                (long) load_hdr->region.regc_vm_size,
3579                region);
3580     }
3581
3582   return;
3583 }
3584
3585 \f
3586 /* Fatal error when {en,de}code_mach_o_header fails.  */
3587
3588 static void
3589 bad_header (status)
3590      int status;
3591 {
3592   char *msg = (char *) 0;
3593
3594   switch (status)
3595     {
3596     case MO_ERROR_BAD_MAGIC:            msg = "bad magic number";               break;
3597     case MO_ERROR_BAD_HDR_VERS:         msg = "bad header version";             break;
3598     case MO_ERROR_BAD_RAW_HDR_VERS:     msg = "bad raw header version";         break;
3599     case MO_ERROR_BUF2SML:              msg = "raw header buffer too small";    break;
3600     case MO_ERROR_OLD_RAW_HDR_FILE:     msg = "old raw header file";            break;
3601     case MO_ERROR_UNSUPPORTED_VERS:     msg = "unsupported version";            break;
3602     }
3603
3604   if (msg == (char *) 0)
3605     fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3606   else
3607     fatal ("%s", msg);
3608 }
3609
3610 \f
3611 /* Read a file into a memory buffer.  */
3612
3613 static struct file_info *
3614 read_file (name, fd, rw)
3615      char *name;                /* filename */
3616      int fd;                    /* file descriptor */
3617      int rw;                    /* read/write */
3618 {
3619   struct stat stat_pkt;
3620   struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3621 #ifdef USE_MMAP
3622   static int page_size;
3623 #endif
3624
3625   if (fstat (fd, &stat_pkt) < 0)
3626     fatal_perror ("fstat %s", name);
3627
3628   p->name         = name;
3629   p->size         = stat_pkt.st_size;
3630   p->rounded_size = stat_pkt.st_size;
3631   p->fd           = fd;
3632   p->rw           = rw;
3633
3634 #ifdef USE_MMAP
3635   if (debug)
3636     fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3637
3638   if (page_size == 0)
3639     page_size = sysconf (_SC_PAGE_SIZE);
3640
3641   p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3642   p->start = mmap ((caddr_t) 0,
3643                    (rw) ? p->rounded_size : p->size,
3644                    (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3645                    MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3646                    fd,
3647                    0L);
3648
3649   if (p->start != (char *) 0 && p->start != (char *) -1)
3650     p->use_mmap = 1;
3651
3652   else
3653 #endif /* USE_MMAP */
3654     {
3655       long len;
3656
3657       if (debug)
3658         fprintf (stderr, "read %s\n", name);
3659
3660       p->use_mmap = 0;
3661       p->start = xmalloc (p->size);
3662       if (lseek (fd, 0L, SEEK_SET) < 0)
3663         fatal_perror ("lseek to 0 on %s", name);
3664
3665       len = read (fd, p->start, p->size);
3666       if (len < 0)
3667         fatal_perror ("read %s", name);
3668
3669       if (len != p->size)
3670         fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3671     }
3672
3673   return p;
3674 }
3675 \f
3676 /* Do anything necessary to write a file back from memory.  */
3677
3678 static void
3679 end_file (ptr)
3680      struct file_info *ptr;     /* file information block */
3681 {
3682 #ifdef USE_MMAP
3683   if (ptr->use_mmap)
3684     {
3685       if (ptr->rw)
3686         {
3687           if (debug)
3688             fprintf (stderr, "msync %s\n", ptr->name);
3689
3690           if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3691             fatal_perror ("msync %s", ptr->name);
3692         }
3693
3694       if (debug)
3695         fprintf (stderr, "munmap %s\n", ptr->name);
3696
3697       if (munmap (ptr->start, ptr->size))
3698         fatal_perror ("munmap %s", ptr->name);
3699     }
3700   else
3701 #endif /* USE_MMAP */
3702     {
3703       if (ptr->rw)
3704         {
3705           long len;
3706
3707           if (debug)
3708             fprintf (stderr, "write %s\n", ptr->name);
3709
3710           if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3711             fatal_perror ("lseek to 0 on %s", ptr->name);
3712
3713           len = write (ptr->fd, ptr->start, ptr->size);
3714           if (len < 0)
3715             fatal_perror ("write %s", ptr->name);
3716
3717           if (len != ptr->size)
3718             fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3719         }
3720
3721       free (ptr->start);
3722     }
3723
3724   free (ptr);
3725 }
3726
3727 #endif /* OBJECT_FORMAT_ROSE */