OSDN Git Service

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