OSDN Git Service

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