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