OSDN Git Service

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