source: trunk/third/gcc/collect2.c @ 11288

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