OSDN Git Service

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