OSDN Git Service

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