OSDN Git Service

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