OSDN Git Service

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