OSDN Git Service

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