OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [collect2.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Collect static initialization info into data structures that can be
2
   traversed by C++ initialization and finalization routines.
3
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4
   2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
5
   Contributed by Chris Smith (csmith@convex.com).
6
   Heavily modified by Michael Meissner (meissner@cygnus.com),
7
   Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8
 
9
This file is part of GCC.
10
 
11
GCC is free software; you can redistribute it and/or modify it under
12
the terms of the GNU General Public License as published by the Free
13
Software Foundation; either version 3, or (at your option) any later
14
version.
15
 
16
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17
WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
for more details.
20
 
21
You should have received a copy of the GNU General Public License
22
along with GCC; see the file COPYING3.  If not see
23
<http://www.gnu.org/licenses/>.  */
24
 
25
 
26
/* Build tables of static constructors and destructors and run ld.  */
27
 
28
#include "config.h"
29
#include "system.h"
30
#include "coretypes.h"
31
#include "tm.h"
32
#include <signal.h>
33
#if ! defined( SIGCHLD ) && defined( SIGCLD )
34
#  define SIGCHLD SIGCLD
35
#endif
36
 
37
#ifndef LIBRARY_PATH_ENV
38
#define LIBRARY_PATH_ENV "LIBRARY_PATH"
39
#endif
40
 
41
#define COLLECT
42
 
43
#include "collect2.h"
44
#include "demangle.h"
45
#include "obstack.h"
46
#include "intl.h"
47
#include "version.h"
48
 
49
/* On certain systems, we have code that works by scanning the object file
50
   directly.  But this code uses system-specific header files and library
51
   functions, so turn it off in a cross-compiler.  Likewise, the names of
52
   the utilities are not correct for a cross-compiler; we have to hope that
53
   cross-versions are in the proper directories.  */
54
 
55
#ifdef CROSS_COMPILE
56
#undef OBJECT_FORMAT_COFF
57
#undef MD_EXEC_PREFIX
58
#undef REAL_LD_FILE_NAME
59
#undef REAL_NM_FILE_NAME
60
#undef REAL_STRIP_FILE_NAME
61
#endif
62
 
63
/* If we cannot use a special method, use the ordinary one:
64
   run nm to find what symbols are present.
65
   In a cross-compiler, this means you need a cross nm,
66
   but that is not quite as unpleasant as special headers.  */
67
 
68
#if !defined (OBJECT_FORMAT_COFF)
69
#define OBJECT_FORMAT_NONE
70
#endif
71
 
72
#ifdef OBJECT_FORMAT_COFF
73
 
74
#include <a.out.h>
75
#include <ar.h>
76
 
77
#ifdef UMAX
78
#include <sgs.h>
79
#endif
80
 
81
/* Many versions of ldfcn.h define these.  */
82
#ifdef FREAD
83
#undef FREAD
84
#undef FWRITE
85
#endif
86
 
87
#include <ldfcn.h>
88
 
89
/* Some systems have an ISCOFF macro, but others do not.  In some cases
90
   the macro may be wrong.  MY_ISCOFF is defined in tm.h files for machines
91
   that either do not have an ISCOFF macro in /usr/include or for those
92
   where it is wrong.  */
93
 
94
#ifndef MY_ISCOFF
95
#define MY_ISCOFF(X) ISCOFF (X)
96
#endif
97
 
98
#endif /* OBJECT_FORMAT_COFF */
99
 
100
#ifdef OBJECT_FORMAT_NONE
101
 
102
/* Default flags to pass to nm.  */
103
#ifndef NM_FLAGS
104
#define NM_FLAGS "-n"
105
#endif
106
 
107
#endif /* OBJECT_FORMAT_NONE */
108
 
109
/* Some systems use __main in a way incompatible with its use in gcc, in these
110
   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
111
   give the same symbol without quotes for an alternative entry point.  */
112
#ifndef NAME__MAIN
113
#define NAME__MAIN "__main"
114
#endif
115
 
116
/* This must match tree.h.  */
117
#define DEFAULT_INIT_PRIORITY 65535
118
 
119
#ifndef COLLECT_SHARED_INIT_FUNC
120
#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
121
  fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
122
#endif
123
#ifndef COLLECT_SHARED_FINI_FUNC
124
#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
125
  fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
126
#endif
127
 
128
#ifdef LDD_SUFFIX
129
#define SCAN_LIBRARIES
130
#endif
131
 
132
#ifdef USE_COLLECT2
133
int do_collecting = 1;
134
#else
135
int do_collecting = 0;
136
#endif
137
 
138
/* Nonzero if we should suppress the automatic demangling of identifiers
139
   in linker error messages.  Set from COLLECT_NO_DEMANGLE.  */
140
int no_demangle;
141
 
142
/* Linked lists of constructor and destructor names.  */
143
 
144
struct id
145
{
146
  struct id *next;
147
  int sequence;
148
  char name[1];
149
};
150
 
151
struct head
152
{
153
  struct id *first;
154
  struct id *last;
155
  int number;
156
};
157
 
158
/* Enumeration giving which pass this is for scanning the program file.  */
159
 
160
enum pass {
161
  PASS_FIRST,                           /* without constructors */
162
  PASS_OBJ,                             /* individual objects */
163
  PASS_LIB,                             /* looking for shared libraries */
164
  PASS_SECOND                           /* with constructors linked in */
165
};
166
 
167
int vflag;                              /* true if -v */
168
static int rflag;                       /* true if -r */
169
static int strip_flag;                  /* true if -s */
170
static const char *demangle_flag;
171
#ifdef COLLECT_EXPORT_LIST
172
static int export_flag;                 /* true if -bE */
173
static int aix64_flag;                  /* true if -b64 */
174
static int aixrtl_flag;                 /* true if -brtl */
175
#endif
176
 
177
int debug;                              /* true if -debug */
178
 
179
static int shared_obj;                  /* true if -shared */
180
 
181
static const char *c_file;              /* <xxx>.c for constructor/destructor list.  */
182
static const char *o_file;              /* <xxx>.o for constructor/destructor list.  */
183
#ifdef COLLECT_EXPORT_LIST
184
static const char *export_file;         /* <xxx>.x for AIX export list.  */
185
#endif
186
const char *ldout;                      /* File for ld stdout.  */
187
const char *lderrout;                   /* File for ld stderr.  */
188
static const char *output_file;         /* Output file for ld.  */
189
static const char *nm_file_name;        /* pathname of nm */
190
#ifdef LDD_SUFFIX
191
static const char *ldd_file_name;       /* pathname of ldd (or equivalent) */
192
#endif
193
static const char *strip_file_name;             /* pathname of strip */
194
const char *c_file_name;                /* pathname of gcc */
195
static char *initname, *fininame;       /* names of init and fini funcs */
196
 
197
static struct head constructors;        /* list of constructors found */
198
static struct head destructors;         /* list of destructors found */
199
#ifdef COLLECT_EXPORT_LIST
200
static struct head exports;             /* list of exported symbols */
201
#endif
202
static struct head frame_tables;        /* list of frame unwind info tables */
203
 
204
struct obstack temporary_obstack;
205
char * temporary_firstobj;
206
 
207
/* Structure to hold all the directories in which to search for files to
208
   execute.  */
209
 
210
struct prefix_list
211
{
212
  const char *prefix;         /* String to prepend to the path.  */
213
  struct prefix_list *next;   /* Next in linked list.  */
214
};
215
 
216
struct path_prefix
217
{
218
  struct prefix_list *plist;  /* List of prefixes to try */
219
  int max_len;                /* Max length of a prefix in PLIST */
220
  const char *name;           /* Name of this list (used in config stuff) */
221
};
222
 
223
#ifdef COLLECT_EXPORT_LIST
224
/* Lists to keep libraries to be scanned for global constructors/destructors.  */
225
static struct head libs;                    /* list of libraries */
226
static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
227
static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
228
static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
229
                                          &libpath_lib_dirs, NULL};
230
#endif
231
 
232
static void handler (int);
233
static int is_ctor_dtor (const char *);
234
static char *find_a_file (struct path_prefix *, const char *);
235
static void add_prefix (struct path_prefix *, const char *);
236
static void prefix_from_env (const char *, struct path_prefix *);
237
static void prefix_from_string (const char *, struct path_prefix *);
238
static void do_wait (const char *, struct pex_obj *);
239
static void fork_execute (const char *, char **);
240
static void maybe_unlink (const char *);
241
static void add_to_list (struct head *, const char *);
242
static int extract_init_priority (const char *);
243
static void sort_ids (struct head *);
244
static void write_list (FILE *, const char *, struct id *);
245
#ifdef COLLECT_EXPORT_LIST
246
static void dump_list (FILE *, const char *, struct id *);
247
#endif
248
#if 0
249
static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
250
#endif
251
static void write_list_with_asm (FILE *, const char *, struct id *);
252
static void write_c_file (FILE *, const char *);
253
static void write_c_file_stat (FILE *, const char *);
254
#ifndef LD_INIT_SWITCH
255
static void write_c_file_glob (FILE *, const char *);
256
#endif
257
static void scan_prog_file (const char *, enum pass);
258
#ifdef SCAN_LIBRARIES
259
static void scan_libraries (const char *);
260
#endif
261
#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
262
static int is_in_args (const char *, const char **, const char **);
263
#endif
264
#ifdef COLLECT_EXPORT_LIST
265
#if 0
266
static int is_in_list (const char *, struct id *);
267
#endif
268
static void write_aix_file (FILE *, struct id *);
269
static char *resolve_lib_name (const char *);
270
#endif
271
static char *extract_string (const char **);
272
 
273
/* Delete tempfiles and exit function.  */
274
 
275
void
276
collect_exit (int status)
277
{
278
  if (c_file != 0 && c_file[0])
279
    maybe_unlink (c_file);
280
 
281
  if (o_file != 0 && o_file[0])
282
    maybe_unlink (o_file);
283
 
284
#ifdef COLLECT_EXPORT_LIST
285
  if (export_file != 0 && export_file[0])
286
    maybe_unlink (export_file);
287
#endif
288
 
289
  if (ldout != 0 && ldout[0])
290
    {
291
      dump_file (ldout, stdout);
292
      maybe_unlink (ldout);
293
    }
294
 
295
  if (lderrout != 0 && lderrout[0])
296
    {
297
      dump_file (lderrout, stderr);
298
      maybe_unlink (lderrout);
299
    }
300
 
301
  if (status != 0 && output_file != 0 && output_file[0])
302
    maybe_unlink (output_file);
303
 
304
  exit (status);
305
}
306
 
307
 
308
/* Notify user of a non-error.  */
309
void
310
notice (const char *cmsgid, ...)
311
{
312
  va_list ap;
313
 
314
  va_start (ap, cmsgid);
315
  vfprintf (stderr, _(cmsgid), ap);
316
  va_end (ap);
317
}
318
 
319
/* Die when sys call fails.  */
320
 
321
void
322
fatal_perror (const char * cmsgid, ...)
323
{
324
  int e = errno;
325
  va_list ap;
326
 
327
  va_start (ap, cmsgid);
328
  fprintf (stderr, "collect2: ");
329
  vfprintf (stderr, _(cmsgid), ap);
330
  fprintf (stderr, ": %s\n", xstrerror (e));
331
  va_end (ap);
332
 
333
  collect_exit (FATAL_EXIT_CODE);
334
}
335
 
336
/* Just die.  */
337
 
338
void
339
fatal (const char * cmsgid, ...)
340
{
341
  va_list ap;
342
 
343
  va_start (ap, cmsgid);
344
  fprintf (stderr, "collect2: ");
345
  vfprintf (stderr, _(cmsgid), ap);
346
  fprintf (stderr, "\n");
347
  va_end (ap);
348
 
349
  collect_exit (FATAL_EXIT_CODE);
350
}
351
 
352
/* Write error message.  */
353
 
354
void
355
error (const char * gmsgid, ...)
356
{
357
  va_list ap;
358
 
359
  va_start (ap, gmsgid);
360
  fprintf (stderr, "collect2: ");
361
  vfprintf (stderr, _(gmsgid), ap);
362
  fprintf (stderr, "\n");
363
  va_end(ap);
364
}
365
 
366
/* In case obstack is linked in, and abort is defined to fancy_abort,
367
   provide a default entry.  */
368
 
369
void
370
fancy_abort (const char *file, int line, const char *func)
371
{
372
  fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
373
}
374
 
375
static void
376
handler (int signo)
377
{
378
  if (c_file != 0 && c_file[0])
379
    maybe_unlink (c_file);
380
 
381
  if (o_file != 0 && o_file[0])
382
    maybe_unlink (o_file);
383
 
384
  if (ldout != 0 && ldout[0])
385
    maybe_unlink (ldout);
386
 
387
  if (lderrout != 0 && lderrout[0])
388
    maybe_unlink (lderrout);
389
 
390
#ifdef COLLECT_EXPORT_LIST
391
  if (export_file != 0 && export_file[0])
392
    maybe_unlink (export_file);
393
#endif
394
 
395
  signal (signo, SIG_DFL);
396
  raise (signo);
397
}
398
 
399
 
400
int
401
file_exists (const char *name)
402
{
403
  return access (name, R_OK) == 0;
404
}
405
 
406
/* Parse a reasonable subset of shell quoting syntax.  */
407
 
408
static char *
409
extract_string (const char **pp)
410
{
411
  const char *p = *pp;
412
  int backquote = 0;
413
  int inside = 0;
414
 
415
  for (;;)
416
    {
417
      char c = *p;
418
      if (c == '\0')
419
        break;
420
      ++p;
421
      if (backquote)
422
        obstack_1grow (&temporary_obstack, c);
423
      else if (! inside && c == ' ')
424
        break;
425
      else if (! inside && c == '\\')
426
        backquote = 1;
427
      else if (c == '\'')
428
        inside = !inside;
429
      else
430
        obstack_1grow (&temporary_obstack, c);
431
    }
432
 
433
  obstack_1grow (&temporary_obstack, '\0');
434
  *pp = p;
435
  return XOBFINISH (&temporary_obstack, char *);
436
}
437
 
438
void
439
dump_file (const char *name, FILE *to)
440
{
441
  FILE *stream = fopen (name, "r");
442
 
443
  if (stream == 0)
444
    return;
445
  while (1)
446
    {
447
      int c;
448
      while (c = getc (stream),
449
             c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
450
        obstack_1grow (&temporary_obstack, c);
451
      if (obstack_object_size (&temporary_obstack) > 0)
452
        {
453
          const char *word, *p;
454
          char *result;
455
          obstack_1grow (&temporary_obstack, '\0');
456
          word = XOBFINISH (&temporary_obstack, const char *);
457
 
458
          if (*word == '.')
459
            ++word, putc ('.', to);
460
          p = word;
461
          if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
462
            p += strlen (USER_LABEL_PREFIX);
463
 
464
#ifdef HAVE_LD_DEMANGLE
465
          result = 0;
466
#else
467
          if (no_demangle)
468
            result = 0;
469
          else
470
            result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
471
#endif
472
 
473
          if (result)
474
            {
475
              int diff;
476
              fputs (result, to);
477
 
478
              diff = strlen (word) - strlen (result);
479
              while (diff > 0 && c == ' ')
480
                --diff, putc (' ', to);
481
              while (diff < 0 && c == ' ')
482
                ++diff, c = getc (stream);
483
 
484
              free (result);
485
            }
486
          else
487
            fputs (word, to);
488
 
489
          fflush (to);
490
          obstack_free (&temporary_obstack, temporary_firstobj);
491
        }
492
      if (c == EOF)
493
        break;
494
      putc (c, to);
495
    }
496
  fclose (stream);
497
}
498
 
499
/* Decide whether the given symbol is: a constructor (1), a destructor
500
   (2), a routine in a shared object that calls all the constructors
501
   (3) or destructors (4), a DWARF exception-handling table (5), or
502
   nothing special (0).  */
503
 
504
static int
505
is_ctor_dtor (const char *s)
506
{
507
  struct names { const char *const name; const int len; const int ret;
508
    const int two_underscores; };
509
 
510
  const struct names *p;
511
  int ch;
512
  const char *orig_s = s;
513
 
514
  static const struct names special[] = {
515
#ifndef NO_DOLLAR_IN_LABEL
516
    { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
517
    { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
518
#else
519
#ifndef NO_DOT_IN_LABEL
520
    { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
521
    { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
522
#endif /* NO_DOT_IN_LABEL */
523
#endif /* NO_DOLLAR_IN_LABEL */
524
    { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
525
    { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
526
    { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
527
    { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
528
    { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
529
    { NULL, 0, 0, 0 }
530
  };
531
 
532
  while ((ch = *s) == '_')
533
    ++s;
534
 
535
  if (s == orig_s)
536
    return 0;
537
 
538
  for (p = &special[0]; p->len > 0; p++)
539
    {
540
      if (ch == p->name[0]
541
          && (!p->two_underscores || ((s - orig_s) >= 2))
542
          && strncmp(s, p->name, p->len) == 0)
543
        {
544
          return p->ret;
545
        }
546
    }
547
  return 0;
548
}
549
 
550
/* We maintain two prefix lists: one from COMPILER_PATH environment variable
551
   and one from the PATH variable.  */
552
 
553
static struct path_prefix cpath, path;
554
 
555
#ifdef CROSS_COMPILE
556
/* This is the name of the target machine.  We use it to form the name
557
   of the files to execute.  */
558
 
559
static const char *const target_machine = TARGET_MACHINE;
560
#endif
561
 
562
/* Search for NAME using prefix list PPREFIX.  We only look for executable
563
   files.
564
 
565
   Return 0 if not found, otherwise return its name, allocated with malloc.  */
566
 
567
static char *
568
find_a_file (struct path_prefix *pprefix, const char *name)
569
{
570
  char *temp;
571
  struct prefix_list *pl;
572
  int len = pprefix->max_len + strlen (name) + 1;
573
 
574
  if (debug)
575
    fprintf (stderr, "Looking for '%s'\n", name);
576
 
577
#ifdef HOST_EXECUTABLE_SUFFIX
578
  len += strlen (HOST_EXECUTABLE_SUFFIX);
579
#endif
580
 
581
  temp = XNEWVEC (char, len);
582
 
583
  /* Determine the filename to execute (special case for absolute paths).  */
584
 
585
  if (*name == '/'
586
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
587
      || (*name && name[1] == ':')
588
#endif
589
      )
590
    {
591
      if (access (name, X_OK) == 0)
592
        {
593
          strcpy (temp, name);
594
 
595
          if (debug)
596
            fprintf (stderr, "  - found: absolute path\n");
597
 
598
          return temp;
599
        }
600
 
601
#ifdef HOST_EXECUTABLE_SUFFIX
602
        /* Some systems have a suffix for executable files.
603
           So try appending that.  */
604
      strcpy (temp, name);
605
        strcat (temp, HOST_EXECUTABLE_SUFFIX);
606
 
607
        if (access (temp, X_OK) == 0)
608
          return temp;
609
#endif
610
 
611
      if (debug)
612
        fprintf (stderr, "  - failed to locate using absolute path\n");
613
    }
614
  else
615
    for (pl = pprefix->plist; pl; pl = pl->next)
616
      {
617
        struct stat st;
618
 
619
        strcpy (temp, pl->prefix);
620
        strcat (temp, name);
621
 
622
        if (stat (temp, &st) >= 0
623
            && ! S_ISDIR (st.st_mode)
624
            && access (temp, X_OK) == 0)
625
          return temp;
626
 
627
#ifdef HOST_EXECUTABLE_SUFFIX
628
        /* Some systems have a suffix for executable files.
629
           So try appending that.  */
630
        strcat (temp, HOST_EXECUTABLE_SUFFIX);
631
 
632
        if (stat (temp, &st) >= 0
633
            && ! S_ISDIR (st.st_mode)
634
            && access (temp, X_OK) == 0)
635
          return temp;
636
#endif
637
      }
638
 
639
  if (debug && pprefix->plist == NULL)
640
    fprintf (stderr, "  - failed: no entries in prefix list\n");
641
 
642
  free (temp);
643
  return 0;
644
}
645
 
646
/* Add an entry for PREFIX to prefix list PPREFIX.  */
647
 
648
static void
649
add_prefix (struct path_prefix *pprefix, const char *prefix)
650
{
651
  struct prefix_list *pl, **prev;
652
  int len;
653
 
654
  if (pprefix->plist)
655
    {
656
      for (pl = pprefix->plist; pl->next; pl = pl->next)
657
        ;
658
      prev = &pl->next;
659
    }
660
  else
661
    prev = &pprefix->plist;
662
 
663
  /* Keep track of the longest prefix.  */
664
 
665
  len = strlen (prefix);
666
  if (len > pprefix->max_len)
667
    pprefix->max_len = len;
668
 
669
  pl = XNEW (struct prefix_list);
670
  pl->prefix = xstrdup (prefix);
671
 
672
  if (*prev)
673
    pl->next = *prev;
674
  else
675
    pl->next = (struct prefix_list *) 0;
676
  *prev = pl;
677
}
678
 
679
/* Take the value of the environment variable ENV, break it into a path, and
680
   add of the entries to PPREFIX.  */
681
 
682
static void
683
prefix_from_env (const char *env, struct path_prefix *pprefix)
684
{
685
  const char *p;
686
  GET_ENVIRONMENT (p, env);
687
 
688
  if (p)
689
    prefix_from_string (p, pprefix);
690
}
691
 
692
static void
693
prefix_from_string (const char *p, struct path_prefix *pprefix)
694
{
695
  const char *startp, *endp;
696
  char *nstore = XNEWVEC (char, strlen (p) + 3);
697
 
698
  if (debug)
699
    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
700
 
701
  startp = endp = p;
702
  while (1)
703
    {
704
      if (*endp == PATH_SEPARATOR || *endp == 0)
705
        {
706
          strncpy (nstore, startp, endp-startp);
707
          if (endp == startp)
708
            {
709
              strcpy (nstore, "./");
710
            }
711
          else if (! IS_DIR_SEPARATOR (endp[-1]))
712
            {
713
              nstore[endp-startp] = DIR_SEPARATOR;
714
              nstore[endp-startp+1] = 0;
715
            }
716
          else
717
            nstore[endp-startp] = 0;
718
 
719
          if (debug)
720
            fprintf (stderr, "  - add prefix: %s\n", nstore);
721
 
722
          add_prefix (pprefix, nstore);
723
          if (*endp == 0)
724
            break;
725
          endp = startp = endp + 1;
726
        }
727
      else
728
        endp++;
729
    }
730
}
731
 
732
/* Main program.  */
733
 
734
int
735
main (int argc, char **argv)
736
{
737
  static const char *const ld_suffix    = "ld";
738
  static const char *const real_ld_suffix = "real-ld";
739
  static const char *const collect_ld_suffix = "collect-ld";
740
  static const char *const nm_suffix    = "nm";
741
  static const char *const gnm_suffix   = "gnm";
742
#ifdef LDD_SUFFIX
743
  static const char *const ldd_suffix   = LDD_SUFFIX;
744
#endif
745
  static const char *const strip_suffix = "strip";
746
  static const char *const gstrip_suffix = "gstrip";
747
 
748
#ifdef CROSS_COMPILE
749
  /* If we look for a program in the compiler directories, we just use
750
     the short name, since these directories are already system-specific.
751
     But it we look for a program in the system directories, we need to
752
     qualify the program name with the target machine.  */
753
 
754
  const char *const full_ld_suffix =
755
    concat(target_machine, "-", ld_suffix, NULL);
756
  const char *const full_nm_suffix =
757
    concat (target_machine, "-", nm_suffix, NULL);
758
  const char *const full_gnm_suffix =
759
    concat (target_machine, "-", gnm_suffix, NULL);
760
#ifdef LDD_SUFFIX
761
  const char *const full_ldd_suffix =
762
    concat (target_machine, "-", ldd_suffix, NULL);
763
#endif
764
  const char *const full_strip_suffix =
765
    concat (target_machine, "-", strip_suffix, NULL);
766
  const char *const full_gstrip_suffix =
767
    concat (target_machine, "-", gstrip_suffix, NULL);
768
#else
769
  const char *const full_ld_suffix      = ld_suffix;
770
  const char *const full_nm_suffix      = nm_suffix;
771
  const char *const full_gnm_suffix     = gnm_suffix;
772
#ifdef LDD_SUFFIX
773
  const char *const full_ldd_suffix     = ldd_suffix;
774
#endif
775
  const char *const full_strip_suffix   = strip_suffix;
776
  const char *const full_gstrip_suffix  = gstrip_suffix;
777
#endif /* CROSS_COMPILE */
778
 
779
  const char *arg;
780
  FILE *outf;
781
#ifdef COLLECT_EXPORT_LIST
782
  FILE *exportf;
783
#endif
784
  const char *ld_file_name;
785
  const char *p;
786
  char **c_argv;
787
  const char **c_ptr;
788
  char **ld1_argv;
789
  const char **ld1;
790
  char **ld2_argv;
791
  const char **ld2;
792
  char **object_lst;
793
  const char **object;
794
  int first_file;
795
  int num_c_args        = argc+9;
796
 
797
  no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
798
 
799
  /* Suppress demangling by the real linker, which may be broken.  */
800
  putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
801
 
802
#if defined (COLLECT2_HOST_INITIALIZATION)
803
  /* Perform system dependent initialization, if necessary.  */
804
  COLLECT2_HOST_INITIALIZATION;
805
#endif
806
 
807
#ifdef SIGCHLD
808
  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
809
     receive the signal.  A different setting is inheritable */
810
  signal (SIGCHLD, SIG_DFL);
811
#endif
812
 
813
  /* Unlock the stdio streams.  */
814
  unlock_std_streams ();
815
 
816
  gcc_init_libintl ();
817
 
818
  /* Do not invoke xcalloc before this point, since locale needs to be
819
     set first, in case a diagnostic is issued.  */
820
 
821
  ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+4));
822
  ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+11));
823
  object = (const char **)(object_lst = xcalloc(sizeof (char *), argc));
824
 
825
#ifdef DEBUG
826
  debug = 1;
827
#endif
828
 
829
  /* Parse command line early for instances of -debug.  This allows
830
     the debug flag to be set before functions like find_a_file()
831
     are called.  */
832
  {
833
    int i;
834
 
835
    for (i = 1; argv[i] != NULL; i ++)
836
      {
837
        if (! strcmp (argv[i], "-debug"))
838
          debug = 1;
839
      }
840
    vflag = debug;
841
  }
842
 
843
#ifndef DEFAULT_A_OUT_NAME
844
  output_file = "a.out";
845
#else
846
  output_file = DEFAULT_A_OUT_NAME;
847
#endif
848
 
849
  obstack_begin (&temporary_obstack, 0);
850
  temporary_firstobj = obstack_alloc (&temporary_obstack, 0);
851
 
852
#ifndef HAVE_LD_DEMANGLE
853
  current_demangling_style = auto_demangling;
854
#endif
855
  p = getenv ("COLLECT_GCC_OPTIONS");
856
  while (p && *p)
857
    {
858
      const char *q = extract_string (&p);
859
      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
860
        num_c_args++;
861
    }
862
  obstack_free (&temporary_obstack, temporary_firstobj);
863
 
864
  /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
865
     -fno-exceptions -w */
866
  num_c_args += 5;
867
 
868
  c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
869
 
870
  if (argc < 2)
871
    fatal ("no arguments");
872
 
873
#ifdef SIGQUIT
874
  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
875
    signal (SIGQUIT, handler);
876
#endif
877
  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
878
    signal (SIGINT, handler);
879
#ifdef SIGALRM
880
  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
881
    signal (SIGALRM, handler);
882
#endif
883
#ifdef SIGHUP
884
  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
885
    signal (SIGHUP, handler);
886
#endif
887
  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
888
    signal (SIGSEGV, handler);
889
#ifdef SIGBUS
890
  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
891
    signal (SIGBUS, handler);
892
#endif
893
 
894
  /* Extract COMPILER_PATH and PATH into our prefix list.  */
895
  prefix_from_env ("COMPILER_PATH", &cpath);
896
  prefix_from_env ("PATH", &path);
897
 
898
  /* Try to discover a valid linker/nm/strip to use.  */
899
 
900
  /* Maybe we know the right file to use (if not cross).  */
901
  ld_file_name = 0;
902
#ifdef DEFAULT_LINKER
903
  if (access (DEFAULT_LINKER, X_OK) == 0)
904
    ld_file_name = DEFAULT_LINKER;
905
  if (ld_file_name == 0)
906
#endif
907
#ifdef REAL_LD_FILE_NAME
908
  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
909
  if (ld_file_name == 0)
910
#endif
911
  /* Search the (target-specific) compiler dirs for ld'.  */
912
  ld_file_name = find_a_file (&cpath, real_ld_suffix);
913
  /* Likewise for `collect-ld'.  */
914
  if (ld_file_name == 0)
915
    ld_file_name = find_a_file (&cpath, collect_ld_suffix);
916
  /* Search the compiler directories for `ld'.  We have protection against
917
     recursive calls in find_a_file.  */
918
  if (ld_file_name == 0)
919
    ld_file_name = find_a_file (&cpath, ld_suffix);
920
  /* Search the ordinary system bin directories
921
     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
922
  if (ld_file_name == 0)
923
    ld_file_name = find_a_file (&path, full_ld_suffix);
924
 
925
#ifdef REAL_NM_FILE_NAME
926
  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
927
  if (nm_file_name == 0)
928
#endif
929
  nm_file_name = find_a_file (&cpath, gnm_suffix);
930
  if (nm_file_name == 0)
931
    nm_file_name = find_a_file (&path, full_gnm_suffix);
932
  if (nm_file_name == 0)
933
    nm_file_name = find_a_file (&cpath, nm_suffix);
934
  if (nm_file_name == 0)
935
    nm_file_name = find_a_file (&path, full_nm_suffix);
936
 
937
#ifdef LDD_SUFFIX
938
  ldd_file_name = find_a_file (&cpath, ldd_suffix);
939
  if (ldd_file_name == 0)
940
    ldd_file_name = find_a_file (&path, full_ldd_suffix);
941
#endif
942
 
943
#ifdef REAL_STRIP_FILE_NAME
944
  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
945
  if (strip_file_name == 0)
946
#endif
947
  strip_file_name = find_a_file (&cpath, gstrip_suffix);
948
  if (strip_file_name == 0)
949
    strip_file_name = find_a_file (&path, full_gstrip_suffix);
950
  if (strip_file_name == 0)
951
    strip_file_name = find_a_file (&cpath, strip_suffix);
952
  if (strip_file_name == 0)
953
    strip_file_name = find_a_file (&path, full_strip_suffix);
954
 
955
  /* Determine the full path name of the C compiler to use.  */
956
  c_file_name = getenv ("COLLECT_GCC");
957
  if (c_file_name == 0)
958
    {
959
#ifdef CROSS_COMPILE
960
      c_file_name = concat (target_machine, "-gcc", NULL);
961
#else
962
      c_file_name = "gcc";
963
#endif
964
    }
965
 
966
  p = find_a_file (&cpath, c_file_name);
967
 
968
  /* Here it should be safe to use the system search path since we should have
969
     already qualified the name of the compiler when it is needed.  */
970
  if (p == 0)
971
    p = find_a_file (&path, c_file_name);
972
 
973
  if (p)
974
    c_file_name = p;
975
 
976
  *ld1++ = *ld2++ = ld_file_name;
977
 
978
  /* Make temp file names.  */
979
  c_file = make_temp_file (".c");
980
  o_file = make_temp_file (".o");
981
#ifdef COLLECT_EXPORT_LIST
982
  export_file = make_temp_file (".x");
983
#endif
984
  ldout = make_temp_file (".ld");
985
  lderrout = make_temp_file (".le");
986
  *c_ptr++ = c_file_name;
987
  *c_ptr++ = "-x";
988
  *c_ptr++ = "c";
989
  *c_ptr++ = "-c";
990
  *c_ptr++ = "-o";
991
  *c_ptr++ = o_file;
992
 
993
#ifdef COLLECT_EXPORT_LIST
994
  /* Generate a list of directories from LIBPATH.  */
995
  prefix_from_env ("LIBPATH", &libpath_lib_dirs);
996
  /* Add to this list also two standard directories where
997
     AIX loader always searches for libraries.  */
998
  add_prefix (&libpath_lib_dirs, "/lib");
999
  add_prefix (&libpath_lib_dirs, "/usr/lib");
1000
#endif
1001
 
1002
  /* Get any options that the upper GCC wants to pass to the sub-GCC.
1003
 
1004
     AIX support needs to know if -shared has been specified before
1005
     parsing commandline arguments.  */
1006
 
1007
  p = getenv ("COLLECT_GCC_OPTIONS");
1008
  while (p && *p)
1009
    {
1010
      const char *q = extract_string (&p);
1011
      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1012
        *c_ptr++ = xstrdup (q);
1013
      if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1014
        *c_ptr++ = xstrdup (q);
1015
      if (strcmp (q, "-shared") == 0)
1016
        shared_obj = 1;
1017
      if (*q == '-' && q[1] == 'B')
1018
        {
1019
          *c_ptr++ = xstrdup (q);
1020
          if (q[2] == 0)
1021
            {
1022
              q = extract_string (&p);
1023
              *c_ptr++ = xstrdup (q);
1024
            }
1025
        }
1026
    }
1027
  obstack_free (&temporary_obstack, temporary_firstobj);
1028
  *c_ptr++ = "-fno-profile-arcs";
1029
  *c_ptr++ = "-fno-test-coverage";
1030
  *c_ptr++ = "-fno-branch-probabilities";
1031
  *c_ptr++ = "-fno-exceptions";
1032
  *c_ptr++ = "-w";
1033
 
1034
  /* !!! When GCC calls collect2,
1035
     it does not know whether it is calling collect2 or ld.
1036
     So collect2 cannot meaningfully understand any options
1037
     except those ld understands.
1038
     If you propose to make GCC pass some other option,
1039
     just imagine what will happen if ld is really ld!!!  */
1040
 
1041
  /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
1042
  /* After the first file, put in the c++ rt0.  */
1043
 
1044
  first_file = 1;
1045
#ifdef HAVE_LD_DEMANGLE
1046
  if (!demangle_flag && !no_demangle)
1047
    demangle_flag = "--demangle";
1048
  if (demangle_flag)
1049
    *ld1++ = *ld2++ = demangle_flag;
1050
#endif
1051
  while ((arg = *++argv) != (char *) 0)
1052
    {
1053
      *ld1++ = *ld2++ = arg;
1054
 
1055
      if (arg[0] == '-')
1056
        {
1057
          switch (arg[1])
1058
            {
1059
#ifdef COLLECT_EXPORT_LIST
1060
            /* We want to disable automatic exports on AIX when user
1061
               explicitly puts an export list in command line */
1062
            case 'b':
1063
              if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1064
                export_flag = 1;
1065
              else if (arg[2] == '6' && arg[3] == '4')
1066
                aix64_flag = 1;
1067
              else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
1068
                aixrtl_flag = 1;
1069
              break;
1070
#endif
1071
 
1072
            case 'd':
1073
              if (!strcmp (arg, "-debug"))
1074
                {
1075
                  /* Already parsed.  */
1076
                  ld1--;
1077
                  ld2--;
1078
                }
1079
              if (!strcmp (arg, "-dynamic-linker") && argv[1])
1080
                {
1081
                  ++argv;
1082
                  *ld1++ = *ld2++ = *argv;
1083
                }
1084
              break;
1085
 
1086
            case 'l':
1087
              if (first_file)
1088
                {
1089
                  /* place o_file BEFORE this argument! */
1090
                  first_file = 0;
1091
                  ld2--;
1092
                  *ld2++ = o_file;
1093
                  *ld2++ = arg;
1094
                }
1095
#ifdef COLLECT_EXPORT_LIST
1096
              {
1097
                /* Resolving full library name.  */
1098
                const char *s = resolve_lib_name (arg+2);
1099
 
1100
                /* Saving a full library name.  */
1101
                add_to_list (&libs, s);
1102
              }
1103
#endif
1104
              break;
1105
 
1106
#ifdef COLLECT_EXPORT_LIST
1107
            /* Saving directories where to search for libraries.  */
1108
            case 'L':
1109
              add_prefix (&cmdline_lib_dirs, arg+2);
1110
              break;
1111
#else
1112
#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1113
            case 'L':
1114
              if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1115
                --ld1;
1116
              break;
1117
#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1118
#endif
1119
 
1120
            case 'o':
1121
              if (arg[2] == '\0')
1122
                output_file = *ld1++ = *ld2++ = *++argv;
1123
              else if (1
1124
#ifdef SWITCHES_NEED_SPACES
1125
                       && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1126
#endif
1127
                       )
1128
 
1129
                output_file = &arg[2];
1130
              break;
1131
 
1132
            case 'r':
1133
              if (arg[2] == '\0')
1134
                rflag = 1;
1135
              break;
1136
 
1137
            case 's':
1138
              if (arg[2] == '\0' && do_collecting)
1139
                {
1140
                  /* We must strip after the nm run, otherwise C++ linking
1141
                     will not work.  Thus we strip in the second ld run, or
1142
                     else with strip if there is no second ld run.  */
1143
                  strip_flag = 1;
1144
                  ld1--;
1145
                }
1146
              break;
1147
 
1148
            case 'v':
1149
              if (arg[2] == '\0')
1150
                vflag = 1;
1151
              break;
1152
 
1153
            case '-':
1154
              if (strcmp (arg, "--no-demangle") == 0)
1155
                {
1156
                  demangle_flag = arg;
1157
                  no_demangle = 1;
1158
                  ld1--;
1159
                  ld2--;
1160
                }
1161
              else if (strncmp (arg, "--demangle", 10) == 0)
1162
                {
1163
                  demangle_flag = arg;
1164
                  no_demangle = 0;
1165
#ifndef HAVE_LD_DEMANGLE
1166
                  if (arg[10] == '=')
1167
                    {
1168
                      enum demangling_styles style
1169
                        = cplus_demangle_name_to_style (arg+11);
1170
                      if (style == unknown_demangling)
1171
                        error ("unknown demangling style '%s'", arg+11);
1172
                      else
1173
                        current_demangling_style = style;
1174
                    }
1175
#endif
1176
                  ld1--;
1177
                  ld2--;
1178
                }
1179
              break;
1180
            }
1181
        }
1182
      else if ((p = strrchr (arg, '.')) != (char *) 0
1183
               && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1184
                   || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1185
                   || strcmp (p, ".obj") == 0))
1186
        {
1187
          if (first_file)
1188
            {
1189
              first_file = 0;
1190
              if (p[1] == 'o')
1191
                *ld2++ = o_file;
1192
              else
1193
                {
1194
                  /* place o_file BEFORE this argument! */
1195
                  ld2--;
1196
                  *ld2++ = o_file;
1197
                  *ld2++ = arg;
1198
                }
1199
            }
1200
          if (p[1] == 'o' || p[1] == 'l')
1201
            *object++ = arg;
1202
#ifdef COLLECT_EXPORT_LIST
1203
          /* libraries can be specified directly, i.e. without -l flag.  */
1204
          else
1205
            {
1206
              /* Saving a full library name.  */
1207
              add_to_list (&libs, arg);
1208
            }
1209
#endif
1210
        }
1211
    }
1212
 
1213
#ifdef COLLECT_EXPORT_LIST
1214
  /* This is added only for debugging purposes.  */
1215
  if (debug)
1216
    {
1217
      fprintf (stderr, "List of libraries:\n");
1218
      dump_list (stderr, "\t", libs.first);
1219
    }
1220
 
1221
  /* The AIX linker will discard static constructors in object files if
1222
     nothing else in the file is referenced, so look at them first.  */
1223
  {
1224
      const char **export_object_lst = (const char **)object_lst;
1225
 
1226
      while (export_object_lst < object)
1227
        scan_prog_file (*export_object_lst++, PASS_OBJ);
1228
  }
1229
  {
1230
    struct id *list = libs.first;
1231
 
1232
    for (; list; list = list->next)
1233
      scan_prog_file (list->name, PASS_FIRST);
1234
  }
1235
 
1236
  if (exports.first)
1237
    {
1238
      char *buf = concat ("-bE:", export_file, NULL);
1239
 
1240
      *ld1++ = buf;
1241
      *ld2++ = buf;
1242
 
1243
      exportf = fopen (export_file, "w");
1244
      if (exportf == (FILE *) 0)
1245
        fatal_perror ("fopen %s", export_file);
1246
      write_aix_file (exportf, exports.first);
1247
      if (fclose (exportf))
1248
        fatal_perror ("fclose %s", export_file);
1249
    }
1250
#endif
1251
 
1252
  *c_ptr++ = c_file;
1253
  *c_ptr = *ld1 = *object = (char *) 0;
1254
 
1255
  if (vflag)
1256
    {
1257
      notice ("collect2 version %s", version_string);
1258
#ifdef TARGET_VERSION
1259
      TARGET_VERSION;
1260
#endif
1261
      fprintf (stderr, "\n");
1262
    }
1263
 
1264
  if (debug)
1265
    {
1266
      const char *ptr;
1267
      fprintf (stderr, "ld_file_name        = %s\n",
1268
               (ld_file_name ? ld_file_name : "not found"));
1269
      fprintf (stderr, "c_file_name         = %s\n",
1270
               (c_file_name ? c_file_name : "not found"));
1271
      fprintf (stderr, "nm_file_name        = %s\n",
1272
               (nm_file_name ? nm_file_name : "not found"));
1273
#ifdef LDD_SUFFIX
1274
      fprintf (stderr, "ldd_file_name       = %s\n",
1275
               (ldd_file_name ? ldd_file_name : "not found"));
1276
#endif
1277
      fprintf (stderr, "strip_file_name     = %s\n",
1278
               (strip_file_name ? strip_file_name : "not found"));
1279
      fprintf (stderr, "c_file              = %s\n",
1280
               (c_file ? c_file : "not found"));
1281
      fprintf (stderr, "o_file              = %s\n",
1282
               (o_file ? o_file : "not found"));
1283
 
1284
      ptr = getenv ("COLLECT_GCC_OPTIONS");
1285
      if (ptr)
1286
        fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1287
 
1288
      ptr = getenv ("COLLECT_GCC");
1289
      if (ptr)
1290
        fprintf (stderr, "COLLECT_GCC         = %s\n", ptr);
1291
 
1292
      ptr = getenv ("COMPILER_PATH");
1293
      if (ptr)
1294
        fprintf (stderr, "COMPILER_PATH       = %s\n", ptr);
1295
 
1296
      ptr = getenv (LIBRARY_PATH_ENV);
1297
      if (ptr)
1298
        fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1299
 
1300
      fprintf (stderr, "\n");
1301
    }
1302
 
1303
  /* Load the program, searching all libraries and attempting to provide
1304
     undefined symbols from repository information.  */
1305
 
1306
  /* On AIX we do this later.  */
1307
#ifndef COLLECT_EXPORT_LIST
1308
  do_tlink (ld1_argv, object_lst);
1309
#endif
1310
 
1311
  /* If -r or they will be run via some other method, do not build the
1312
     constructor or destructor list, just return now.  */
1313
  if (rflag
1314
#ifndef COLLECT_EXPORT_LIST
1315
      || ! do_collecting
1316
#endif
1317
      )
1318
    {
1319
#ifdef COLLECT_EXPORT_LIST
1320
      /* Do the link we avoided above if we are exiting.  */
1321
      do_tlink (ld1_argv, object_lst);
1322
 
1323
      /* But make sure we delete the export file we may have created.  */
1324
      if (export_file != 0 && export_file[0])
1325
        maybe_unlink (export_file);
1326
#endif
1327
      maybe_unlink (c_file);
1328
      maybe_unlink (o_file);
1329
      return 0;
1330
    }
1331
 
1332
  /* Examine the namelist with nm and search it for static constructors
1333
     and destructors to call.
1334
     Write the constructor and destructor tables to a .s file and reload.  */
1335
 
1336
  /* On AIX we already scanned for global constructors/destructors.  */
1337
#ifndef COLLECT_EXPORT_LIST
1338
  scan_prog_file (output_file, PASS_FIRST);
1339
#endif
1340
 
1341
#ifdef SCAN_LIBRARIES
1342
  scan_libraries (output_file);
1343
#endif
1344
 
1345
  if (debug)
1346
    {
1347
      notice ("%d constructor(s) found\n", constructors.number);
1348
      notice ("%d destructor(s)  found\n", destructors.number);
1349
      notice ("%d frame table(s) found\n", frame_tables.number);
1350
    }
1351
 
1352
  if (constructors.number == 0 && destructors.number == 0
1353
      && frame_tables.number == 0
1354
#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1355
      /* If we will be running these functions ourselves, we want to emit
1356
         stubs into the shared library so that we do not have to relink
1357
         dependent programs when we add static objects.  */
1358
      && ! shared_obj
1359
#endif
1360
      )
1361
    {
1362
#ifdef COLLECT_EXPORT_LIST
1363
      /* Do tlink without additional code generation.  */
1364
      do_tlink (ld1_argv, object_lst);
1365
#endif
1366
      /* Strip now if it was requested on the command line.  */
1367
      if (strip_flag)
1368
        {
1369
          char **real_strip_argv = XCNEWVEC (char *, 3);
1370
          const char ** strip_argv = (const char **) real_strip_argv;
1371
 
1372
          strip_argv[0] = strip_file_name;
1373
          strip_argv[1] = output_file;
1374
          strip_argv[2] = (char *) 0;
1375
          fork_execute ("strip", real_strip_argv);
1376
        }
1377
 
1378
#ifdef COLLECT_EXPORT_LIST
1379
      maybe_unlink (export_file);
1380
#endif
1381
      maybe_unlink (c_file);
1382
      maybe_unlink (o_file);
1383
      return 0;
1384
    }
1385
 
1386
  /* Sort ctor and dtor lists by priority.  */
1387
  sort_ids (&constructors);
1388
  sort_ids (&destructors);
1389
 
1390
  maybe_unlink(output_file);
1391
  outf = fopen (c_file, "w");
1392
  if (outf == (FILE *) 0)
1393
    fatal_perror ("fopen %s", c_file);
1394
 
1395
  write_c_file (outf, c_file);
1396
 
1397
  if (fclose (outf))
1398
    fatal_perror ("fclose %s", c_file);
1399
 
1400
  /* Tell the linker that we have initializer and finalizer functions.  */
1401
#ifdef LD_INIT_SWITCH
1402
#ifdef COLLECT_EXPORT_LIST
1403
  *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1404
#else
1405
  *ld2++ = LD_INIT_SWITCH;
1406
  *ld2++ = initname;
1407
  *ld2++ = LD_FINI_SWITCH;
1408
  *ld2++ = fininame;
1409
#endif
1410
#endif
1411
 
1412
#ifdef COLLECT_EXPORT_LIST
1413
  if (shared_obj)
1414
    {
1415
      /* If we did not add export flag to link arguments before, add it to
1416
         second link phase now.  No new exports should have been added.  */
1417
      if (! exports.first)
1418
        *ld2++ = concat ("-bE:", export_file, NULL);
1419
 
1420
#ifndef LD_INIT_SWITCH
1421
      add_to_list (&exports, initname);
1422
      add_to_list (&exports, fininame);
1423
      add_to_list (&exports, "_GLOBAL__DI");
1424
      add_to_list (&exports, "_GLOBAL__DD");
1425
#endif
1426
      exportf = fopen (export_file, "w");
1427
      if (exportf == (FILE *) 0)
1428
        fatal_perror ("fopen %s", export_file);
1429
      write_aix_file (exportf, exports.first);
1430
      if (fclose (exportf))
1431
        fatal_perror ("fclose %s", export_file);
1432
    }
1433
#endif
1434
 
1435
  /* End of arguments to second link phase.  */
1436
  *ld2 = (char*) 0;
1437
 
1438
  if (debug)
1439
    {
1440
      fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1441
               output_file, c_file);
1442
      write_c_file (stderr, "stderr");
1443
      fprintf (stderr, "========== end of c_file\n\n");
1444
#ifdef COLLECT_EXPORT_LIST
1445
      fprintf (stderr, "\n========== export_file = %s\n", export_file);
1446
      write_aix_file (stderr, exports.first);
1447
      fprintf (stderr, "========== end of export_file\n\n");
1448
#endif
1449
    }
1450
 
1451
  /* Assemble the constructor and destructor tables.
1452
     Link the tables in with the rest of the program.  */
1453
 
1454
  fork_execute ("gcc",  c_argv);
1455
#ifdef COLLECT_EXPORT_LIST
1456
  /* On AIX we must call tlink because of possible templates resolution.  */
1457
  do_tlink (ld2_argv, object_lst);
1458
#else
1459
  /* Otherwise, simply call ld because tlink is already done.  */
1460
  fork_execute ("ld", ld2_argv);
1461
 
1462
  /* Let scan_prog_file do any final mods (OSF/rose needs this for
1463
     constructors/destructors in shared libraries.  */
1464
  scan_prog_file (output_file, PASS_SECOND);
1465
#endif
1466
 
1467
  maybe_unlink (c_file);
1468
  maybe_unlink (o_file);
1469
 
1470
#ifdef COLLECT_EXPORT_LIST
1471
  maybe_unlink (export_file);
1472
#endif
1473
 
1474
  return 0;
1475
}
1476
 
1477
 
1478
/* Wait for a process to finish, and exit if a nonzero status is found.  */
1479
 
1480
int
1481
collect_wait (const char *prog, struct pex_obj *pex)
1482
{
1483
  int status;
1484
 
1485
  if (!pex_get_status (pex, 1, &status))
1486
    fatal_perror ("can't get program status");
1487
  pex_free (pex);
1488
 
1489
  if (status)
1490
    {
1491
      if (WIFSIGNALED (status))
1492
        {
1493
          int sig = WTERMSIG (status);
1494
          error ("%s terminated with signal %d [%s]%s",
1495
                 prog, sig, strsignal(sig),
1496
                 WCOREDUMP(status) ? ", core dumped" : "");
1497
          collect_exit (FATAL_EXIT_CODE);
1498
        }
1499
 
1500
      if (WIFEXITED (status))
1501
        return WEXITSTATUS (status);
1502
    }
1503
  return 0;
1504
}
1505
 
1506
static void
1507
do_wait (const char *prog, struct pex_obj *pex)
1508
{
1509
  int ret = collect_wait (prog, pex);
1510
  if (ret != 0)
1511
    {
1512
      error ("%s returned %d exit status", prog, ret);
1513
      collect_exit (ret);
1514
    }
1515
}
1516
 
1517
 
1518
/* Execute a program, and wait for the reply.  */
1519
 
1520
struct pex_obj *
1521
collect_execute (const char *prog, char **argv, const char *outname,
1522
                 const char *errname)
1523
{
1524
  struct pex_obj *pex;
1525
  const char *errmsg;
1526
  int err;
1527
 
1528
  if (vflag || debug)
1529
    {
1530
      char **p_argv;
1531
      const char *str;
1532
 
1533
      if (argv[0])
1534
        fprintf (stderr, "%s", argv[0]);
1535
      else
1536
        notice ("[cannot find %s]", prog);
1537
 
1538
      for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1539
        fprintf (stderr, " %s", str);
1540
 
1541
      fprintf (stderr, "\n");
1542
    }
1543
 
1544
  fflush (stdout);
1545
  fflush (stderr);
1546
 
1547
  /* If we cannot find a program we need, complain error.  Do this here
1548
     since we might not end up needing something that we could not find.  */
1549
 
1550
  if (argv[0] == 0)
1551
    fatal ("cannot find '%s'", prog);
1552
 
1553
  pex = pex_init (0, "collect2", NULL);
1554
  if (pex == NULL)
1555
    fatal_perror ("pex_init failed");
1556
 
1557
  errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, outname,
1558
                    errname, &err);
1559
  if (errmsg != NULL)
1560
    {
1561
      if (err != 0)
1562
        {
1563
          errno = err;
1564
          fatal_perror (errmsg);
1565
        }
1566
      else
1567
        fatal (errmsg);
1568
    }
1569
 
1570
  return pex;
1571
}
1572
 
1573
static void
1574
fork_execute (const char *prog, char **argv)
1575
{
1576
  struct pex_obj *pex;
1577
 
1578
  pex = collect_execute (prog, argv, NULL, NULL);
1579
  do_wait (prog, pex);
1580
}
1581
 
1582
/* Unlink a file unless we are debugging.  */
1583
 
1584
static void
1585
maybe_unlink (const char *file)
1586
{
1587
  if (!debug)
1588
    unlink_if_ordinary (file);
1589
  else
1590
    notice ("[Leaving %s]\n", file);
1591
}
1592
 
1593
 
1594
static long sequence_number = 0;
1595
 
1596
/* Add a name to a linked list.  */
1597
 
1598
static void
1599
add_to_list (struct head *head_ptr, const char *name)
1600
{
1601
  struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1);
1602
  struct id *p;
1603
  strcpy (newid->name, name);
1604
 
1605
  if (head_ptr->first)
1606
    head_ptr->last->next = newid;
1607
  else
1608
    head_ptr->first = newid;
1609
 
1610
  /* Check for duplicate symbols.  */
1611
  for (p = head_ptr->first;
1612
       strcmp (name, p->name) != 0;
1613
       p = p->next)
1614
    ;
1615
  if (p != newid)
1616
    {
1617
      head_ptr->last->next = 0;
1618
      free (newid);
1619
      return;
1620
    }
1621
 
1622
  newid->sequence = ++sequence_number;
1623
  head_ptr->last = newid;
1624
  head_ptr->number++;
1625
}
1626
 
1627
/* Grab the init priority number from an init function name that
1628
   looks like "_GLOBAL_.I.12345.foo".  */
1629
 
1630
static int
1631
extract_init_priority (const char *name)
1632
{
1633
  int pos = 0, pri;
1634
 
1635
  while (name[pos] == '_')
1636
    ++pos;
1637
  pos += 10; /* strlen ("GLOBAL__X_") */
1638
 
1639
  /* Extract init_p number from ctor/dtor name.  */
1640
  pri = atoi (name + pos);
1641
  return pri ? pri : DEFAULT_INIT_PRIORITY;
1642
}
1643
 
1644
/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1645
   ctors will be run from right to left, dtors from left to right.  */
1646
 
1647
static void
1648
sort_ids (struct head *head_ptr)
1649
{
1650
  /* id holds the current element to insert.  id_next holds the next
1651
     element to insert.  id_ptr iterates through the already sorted elements
1652
     looking for the place to insert id.  */
1653
  struct id *id, *id_next, **id_ptr;
1654
 
1655
  id = head_ptr->first;
1656
 
1657
  /* We don't have any sorted elements yet.  */
1658
  head_ptr->first = NULL;
1659
 
1660
  for (; id; id = id_next)
1661
    {
1662
      id_next = id->next;
1663
      id->sequence = extract_init_priority (id->name);
1664
 
1665
      for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1666
        if (*id_ptr == NULL
1667
            /* If the sequence numbers are the same, we put the id from the
1668
               file later on the command line later in the list.  */
1669
            || id->sequence > (*id_ptr)->sequence
1670
            /* Hack: do lexical compare, too.
1671
            || (id->sequence == (*id_ptr)->sequence
1672
                && strcmp (id->name, (*id_ptr)->name) > 0) */
1673
            )
1674
          {
1675
            id->next = *id_ptr;
1676
            *id_ptr = id;
1677
            break;
1678
          }
1679
    }
1680
 
1681
  /* Now set the sequence numbers properly so write_c_file works.  */
1682
  for (id = head_ptr->first; id; id = id->next)
1683
    id->sequence = ++sequence_number;
1684
}
1685
 
1686
/* Write: `prefix', the names on list LIST, `suffix'.  */
1687
 
1688
static void
1689
write_list (FILE *stream, const char *prefix, struct id *list)
1690
{
1691
  while (list)
1692
    {
1693
      fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1694
      list = list->next;
1695
    }
1696
}
1697
 
1698
#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1699
/* Given a STRING, return nonzero if it occurs in the list in range
1700
   [ARGS_BEGIN,ARGS_END).  */
1701
 
1702
static int
1703
is_in_args (const char *string, const char **args_begin,
1704
            const char **args_end)
1705
{
1706
  const char **args_pointer;
1707
  for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1708
    if (strcmp (string, *args_pointer) == 0)
1709
      return 1;
1710
  return 0;
1711
}
1712
#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1713
 
1714
#ifdef COLLECT_EXPORT_LIST
1715
/* This function is really used only on AIX, but may be useful.  */
1716
#if 0
1717
static int
1718
is_in_list (const char *prefix, struct id *list)
1719
{
1720
  while (list)
1721
    {
1722
      if (!strcmp (prefix, list->name)) return 1;
1723
      list = list->next;
1724
    }
1725
    return 0;
1726
}
1727
#endif
1728
#endif /* COLLECT_EXPORT_LIST */
1729
 
1730
/* Added for debugging purpose.  */
1731
#ifdef COLLECT_EXPORT_LIST
1732
static void
1733
dump_list (FILE *stream, const char *prefix, struct id *list)
1734
{
1735
  while (list)
1736
    {
1737
      fprintf (stream, "%s%s,\n", prefix, list->name);
1738
      list = list->next;
1739
    }
1740
}
1741
#endif
1742
 
1743
#if 0
1744
static void
1745
dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
1746
{
1747
  while (list)
1748
    {
1749
      fprintf (stream, "%s%s,\n", prefix, list->prefix);
1750
      list = list->next;
1751
    }
1752
}
1753
#endif
1754
 
1755
static void
1756
write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
1757
{
1758
  while (list)
1759
    {
1760
      fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1761
               prefix, list->sequence, list->name);
1762
      list = list->next;
1763
    }
1764
}
1765
 
1766
/* Write out the constructor and destructor tables statically (for a shared
1767
   object), along with the functions to execute them.  */
1768
 
1769
static void
1770
write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1771
{
1772
  const char *p, *q;
1773
  char *prefix, *r;
1774
  int frames = (frame_tables.number > 0);
1775
 
1776
  /* Figure out name of output_file, stripping off .so version.  */
1777
  p = strrchr (output_file, '/');
1778
  if (p == 0)
1779
    p = output_file;
1780
  else
1781
    p++;
1782
  q = p;
1783
  while (q)
1784
    {
1785
      q = strchr (q,'.');
1786
      if (q == 0)
1787
        {
1788
          q = p + strlen (p);
1789
          break;
1790
        }
1791
      else
1792
        {
1793
          if (strncmp (q, ".so", 3) == 0)
1794
            {
1795
              q += 3;
1796
              break;
1797
            }
1798
          else
1799
            q++;
1800
        }
1801
    }
1802
  /* q points to null at end of the string (or . of the .so version) */
1803
  prefix = XNEWVEC (char, q - p + 1);
1804
  strncpy (prefix, p, q - p);
1805
  prefix[q - p] = 0;
1806
  for (r = prefix; *r; r++)
1807
    if (!ISALNUM ((unsigned char)*r))
1808
      *r = '_';
1809
  if (debug)
1810
    notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1811
            output_file, prefix);
1812
 
1813
  initname = concat ("_GLOBAL__FI_", prefix, NULL);
1814
  fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1815
 
1816
  free (prefix);
1817
 
1818
  /* Write the tables as C code.  */
1819
 
1820
  fprintf (stream, "static int count;\n");
1821
  fprintf (stream, "typedef void entry_pt();\n");
1822
  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1823
 
1824
  if (frames)
1825
    {
1826
      write_list_with_asm (stream, "extern void *", frame_tables.first);
1827
 
1828
      fprintf (stream, "\tstatic void *frame_table[] = {\n");
1829
      write_list (stream, "\t\t&", frame_tables.first);
1830
      fprintf (stream, "\t0\n};\n");
1831
 
1832
      /* This must match what's in frame.h.  */
1833
      fprintf (stream, "struct object {\n");
1834
      fprintf (stream, "  void *pc_begin;\n");
1835
      fprintf (stream, "  void *pc_end;\n");
1836
      fprintf (stream, "  void *fde_begin;\n");
1837
      fprintf (stream, "  void *fde_array;\n");
1838
      fprintf (stream, "  __SIZE_TYPE__ count;\n");
1839
      fprintf (stream, "  struct object *next;\n");
1840
      fprintf (stream, "};\n");
1841
 
1842
      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1843
      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1844
 
1845
      fprintf (stream, "static void reg_frame () {\n");
1846
      fprintf (stream, "\tstatic struct object ob;\n");
1847
      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1848
      fprintf (stream, "\t}\n");
1849
 
1850
      fprintf (stream, "static void dereg_frame () {\n");
1851
      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1852
      fprintf (stream, "\t}\n");
1853
    }
1854
 
1855
  fprintf (stream, "void %s() {\n", initname);
1856
  if (constructors.number > 0 || frames)
1857
    {
1858
      fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1859
      write_list (stream, "\t\t", constructors.first);
1860
      if (frames)
1861
        fprintf (stream, "\treg_frame,\n");
1862
      fprintf (stream, "\t};\n");
1863
      fprintf (stream, "\tentry_pt **p;\n");
1864
      fprintf (stream, "\tif (count++ != 0) return;\n");
1865
      fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1866
      fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1867
    }
1868
  else
1869
    fprintf (stream, "\t++count;\n");
1870
  fprintf (stream, "}\n");
1871
  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1872
  fprintf (stream, "void %s() {\n", fininame);
1873
  if (destructors.number > 0 || frames)
1874
    {
1875
      fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1876
      write_list (stream, "\t\t", destructors.first);
1877
      if (frames)
1878
        fprintf (stream, "\tdereg_frame,\n");
1879
      fprintf (stream, "\t};\n");
1880
      fprintf (stream, "\tentry_pt **p;\n");
1881
      fprintf (stream, "\tif (--count != 0) return;\n");
1882
      fprintf (stream, "\tp = dtors;\n");
1883
      fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1884
               destructors.number + frames);
1885
    }
1886
  fprintf (stream, "}\n");
1887
 
1888
  if (shared_obj)
1889
    {
1890
      COLLECT_SHARED_INIT_FUNC(stream, initname);
1891
      COLLECT_SHARED_FINI_FUNC(stream, fininame);
1892
    }
1893
}
1894
 
1895
/* Write the constructor/destructor tables.  */
1896
 
1897
#ifndef LD_INIT_SWITCH
1898
static void
1899
write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1900
{
1901
  /* Write the tables as C code.  */
1902
 
1903
  int frames = (frame_tables.number > 0);
1904
 
1905
  fprintf (stream, "typedef void entry_pt();\n\n");
1906
 
1907
  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1908
 
1909
  if (frames)
1910
    {
1911
      write_list_with_asm (stream, "extern void *", frame_tables.first);
1912
 
1913
      fprintf (stream, "\tstatic void *frame_table[] = {\n");
1914
      write_list (stream, "\t\t&", frame_tables.first);
1915
      fprintf (stream, "\t0\n};\n");
1916
 
1917
      /* This must match what's in frame.h.  */
1918
      fprintf (stream, "struct object {\n");
1919
      fprintf (stream, "  void *pc_begin;\n");
1920
      fprintf (stream, "  void *pc_end;\n");
1921
      fprintf (stream, "  void *fde_begin;\n");
1922
      fprintf (stream, "  void *fde_array;\n");
1923
      fprintf (stream, "  __SIZE_TYPE__ count;\n");
1924
      fprintf (stream, "  struct object *next;\n");
1925
      fprintf (stream, "};\n");
1926
 
1927
      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1928
      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1929
 
1930
      fprintf (stream, "static void reg_frame () {\n");
1931
      fprintf (stream, "\tstatic struct object ob;\n");
1932
      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1933
      fprintf (stream, "\t}\n");
1934
 
1935
      fprintf (stream, "static void dereg_frame () {\n");
1936
      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1937
      fprintf (stream, "\t}\n");
1938
    }
1939
 
1940
  fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1941
  fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1942
  write_list (stream, "\t", constructors.first);
1943
  if (frames)
1944
    fprintf (stream, "\treg_frame,\n");
1945
  fprintf (stream, "\t0\n};\n\n");
1946
 
1947
  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1948
 
1949
  fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1950
  fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
1951
  write_list (stream, "\t", destructors.first);
1952
  if (frames)
1953
    fprintf (stream, "\tdereg_frame,\n");
1954
  fprintf (stream, "\t0\n};\n\n");
1955
 
1956
  fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1957
  fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1958
}
1959
#endif /* ! LD_INIT_SWITCH */
1960
 
1961
static void
1962
write_c_file (FILE *stream, const char *name)
1963
{
1964
  fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1965
#ifndef LD_INIT_SWITCH
1966
  if (! shared_obj)
1967
    write_c_file_glob (stream, name);
1968
  else
1969
#endif
1970
    write_c_file_stat (stream, name);
1971
  fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1972
}
1973
 
1974
#ifdef COLLECT_EXPORT_LIST
1975
static void
1976
write_aix_file (FILE *stream, struct id *list)
1977
{
1978
  for (; list; list = list->next)
1979
    {
1980
      fputs (list->name, stream);
1981
      putc ('\n', stream);
1982
    }
1983
}
1984
#endif
1985
 
1986
#ifdef OBJECT_FORMAT_NONE
1987
 
1988
/* Generic version to scan the name list of the loaded program for
1989
   the symbols g++ uses for static constructors and destructors.
1990
 
1991
   The constructor table begins at __CTOR_LIST__ and contains a count
1992
   of the number of pointers (or -1 if the constructors are built in a
1993
   separate section by the linker), followed by the pointers to the
1994
   constructor functions, terminated with a null pointer.  The
1995
   destructor table has the same format, and begins at __DTOR_LIST__.  */
1996
 
1997
static void
1998
scan_prog_file (const char *prog_name, enum pass which_pass)
1999
{
2000
  void (*int_handler) (int);
2001
#ifdef SIGQUIT
2002
  void (*quit_handler) (int);
2003
#endif
2004
  char *real_nm_argv[4];
2005
  const char **nm_argv = (const char **) real_nm_argv;
2006
  int argc = 0;
2007
  struct pex_obj *pex;
2008
  const char *errmsg;
2009
  int err;
2010
  char *p, buf[1024];
2011
  FILE *inf;
2012
 
2013
  if (which_pass == PASS_SECOND)
2014
    return;
2015
 
2016
  /* If we do not have an `nm', complain.  */
2017
  if (nm_file_name == 0)
2018
    fatal ("cannot find 'nm'");
2019
 
2020
  nm_argv[argc++] = nm_file_name;
2021
  if (NM_FLAGS[0] != '\0')
2022
    nm_argv[argc++] = NM_FLAGS;
2023
 
2024
  nm_argv[argc++] = prog_name;
2025
  nm_argv[argc++] = (char *) 0;
2026
 
2027
  /* Trace if needed.  */
2028
  if (vflag)
2029
    {
2030
      const char **p_argv;
2031
      const char *str;
2032
 
2033
      for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2034
        fprintf (stderr, " %s", str);
2035
 
2036
      fprintf (stderr, "\n");
2037
    }
2038
 
2039
  fflush (stdout);
2040
  fflush (stderr);
2041
 
2042
  pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2043
  if (pex == NULL)
2044
    fatal_perror ("pex_init failed");
2045
 
2046
  errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, NULL, &err);
2047
  if (errmsg != NULL)
2048
    {
2049
      if (err != 0)
2050
        {
2051
          errno = err;
2052
          fatal_perror (errmsg);
2053
        }
2054
      else
2055
        fatal (errmsg);
2056
    }
2057
 
2058
  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
2059
#ifdef SIGQUIT
2060
  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2061
#endif
2062
 
2063
  inf = pex_read_output (pex, 0);
2064
  if (inf == NULL)
2065
    fatal_perror ("can't open nm output");
2066
 
2067
  if (debug)
2068
    fprintf (stderr, "\nnm output with constructors/destructors.\n");
2069
 
2070
  /* Read each line of nm output.  */
2071
  while (fgets (buf, sizeof buf, inf) != (char *) 0)
2072
    {
2073
      int ch, ch2;
2074
      char *name, *end;
2075
 
2076
      /* If it contains a constructor or destructor name, add the name
2077
         to the appropriate list.  */
2078
 
2079
      for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2080
        if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2081
          break;
2082
 
2083
      if (ch != '_')
2084
        continue;
2085
 
2086
      name = p;
2087
      /* Find the end of the symbol name.
2088
         Do not include `|', because Encore nm can tack that on the end.  */
2089
      for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2090
           end++)
2091
        continue;
2092
 
2093
 
2094
      *end = '\0';
2095
      switch (is_ctor_dtor (name))
2096
        {
2097
        case 1:
2098
          if (which_pass != PASS_LIB)
2099
            add_to_list (&constructors, name);
2100
          break;
2101
 
2102
        case 2:
2103
          if (which_pass != PASS_LIB)
2104
            add_to_list (&destructors, name);
2105
          break;
2106
 
2107
        case 3:
2108
          if (which_pass != PASS_LIB)
2109
            fatal ("init function found in object %s", prog_name);
2110
#ifndef LD_INIT_SWITCH
2111
          add_to_list (&constructors, name);
2112
#endif
2113
          break;
2114
 
2115
        case 4:
2116
          if (which_pass != PASS_LIB)
2117
            fatal ("fini function found in object %s", prog_name);
2118
#ifndef LD_FINI_SWITCH
2119
          add_to_list (&destructors, name);
2120
#endif
2121
          break;
2122
 
2123
        case 5:
2124
          if (which_pass != PASS_LIB)
2125
            add_to_list (&frame_tables, name);
2126
          break;
2127
 
2128
        default:                /* not a constructor or destructor */
2129
          continue;
2130
        }
2131
 
2132
      if (debug)
2133
        fprintf (stderr, "\t%s\n", buf);
2134
    }
2135
 
2136
  if (debug)
2137
    fprintf (stderr, "\n");
2138
 
2139
  do_wait (nm_file_name, pex);
2140
 
2141
  signal (SIGINT,  int_handler);
2142
#ifdef SIGQUIT
2143
  signal (SIGQUIT, quit_handler);
2144
#endif
2145
}
2146
 
2147
#ifdef LDD_SUFFIX
2148
 
2149
/* Use the List Dynamic Dependencies program to find shared libraries that
2150
   the output file depends upon and their initialization/finalization
2151
   routines, if any.  */
2152
 
2153
static void
2154
scan_libraries (const char *prog_name)
2155
{
2156
  static struct head libraries;         /* list of shared libraries found */
2157
  struct id *list;
2158
  void (*int_handler) (int);
2159
#ifdef SIGQUIT
2160
  void (*quit_handler) (int);
2161
#endif
2162
  char *real_ldd_argv[4];
2163
  const char **ldd_argv = (const char **) real_ldd_argv;
2164
  int argc = 0;
2165
  struct pex_obj *pex;
2166
  const char *errmsg;
2167
  int err;
2168
  char buf[1024];
2169
  FILE *inf;
2170
 
2171
  /* If we do not have an `ldd', complain.  */
2172
  if (ldd_file_name == 0)
2173
    {
2174
      error ("cannot find 'ldd'");
2175
      return;
2176
    }
2177
 
2178
  ldd_argv[argc++] = ldd_file_name;
2179
  ldd_argv[argc++] = prog_name;
2180
  ldd_argv[argc++] = (char *) 0;
2181
 
2182
  /* Trace if needed.  */
2183
  if (vflag)
2184
    {
2185
      const char **p_argv;
2186
      const char *str;
2187
 
2188
      for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2189
        fprintf (stderr, " %s", str);
2190
 
2191
      fprintf (stderr, "\n");
2192
    }
2193
 
2194
  fflush (stdout);
2195
  fflush (stderr);
2196
 
2197
  pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2198
  if (pex == NULL)
2199
    fatal_perror ("pex_init failed");
2200
 
2201
  errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
2202
  if (errmsg != NULL)
2203
    {
2204
      if (err != 0)
2205
        {
2206
          errno = err;
2207
          fatal_perror (errmsg);
2208
        }
2209
      else
2210
        fatal (errmsg);
2211
    }
2212
 
2213
  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
2214
#ifdef SIGQUIT
2215
  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2216
#endif
2217
 
2218
  inf = pex_read_output (pex, 0);
2219
  if (inf == NULL)
2220
    fatal_perror ("can't open ldd output");
2221
 
2222
  if (debug)
2223
    notice ("\nldd output with constructors/destructors.\n");
2224
 
2225
  /* Read each line of ldd output.  */
2226
  while (fgets (buf, sizeof buf, inf) != (char *) 0)
2227
    {
2228
      int ch2;
2229
      char *name, *end, *p = buf;
2230
 
2231
      /* Extract names of libraries and add to list.  */
2232
      PARSE_LDD_OUTPUT (p);
2233
      if (p == 0)
2234
        continue;
2235
 
2236
      name = p;
2237
      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2238
        fatal ("dynamic dependency %s not found", buf);
2239
 
2240
      /* Find the end of the symbol name.  */
2241
      for (end = p;
2242
           (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2243
           end++)
2244
        continue;
2245
      *end = '\0';
2246
 
2247
      if (access (name, R_OK) == 0)
2248
        add_to_list (&libraries, name);
2249
      else
2250
        fatal ("unable to open dynamic dependency '%s'", buf);
2251
 
2252
      if (debug)
2253
        fprintf (stderr, "\t%s\n", buf);
2254
    }
2255
  if (debug)
2256
    fprintf (stderr, "\n");
2257
 
2258
  do_wait (ldd_file_name, pex);
2259
 
2260
  signal (SIGINT,  int_handler);
2261
#ifdef SIGQUIT
2262
  signal (SIGQUIT, quit_handler);
2263
#endif
2264
 
2265
  /* Now iterate through the library list adding their symbols to
2266
     the list.  */
2267
  for (list = libraries.first; list; list = list->next)
2268
    scan_prog_file (list->name, PASS_LIB);
2269
}
2270
 
2271
#endif /* LDD_SUFFIX */
2272
 
2273
#endif /* OBJECT_FORMAT_NONE */
2274
 
2275
 
2276
/*
2277
 * COFF specific stuff.
2278
 */
2279
 
2280
#ifdef OBJECT_FORMAT_COFF
2281
 
2282
#if defined (EXTENDED_COFF)
2283
 
2284
#   define GCC_SYMBOLS(X)       (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2285
#   define GCC_SYMENT           SYMR
2286
#   define GCC_OK_SYMBOL(X)     ((X).st == stProc || (X).st == stGlobal)
2287
#   define GCC_SYMINC(X)        (1)
2288
#   define GCC_SYMZERO(X)       (SYMHEADER(X).isymMax)
2289
#   define GCC_CHECK_HDR(X)     (PSYMTAB(X) != 0)
2290
 
2291
#else
2292
 
2293
#   define GCC_SYMBOLS(X)       (HEADER(ldptr).f_nsyms)
2294
#   define GCC_SYMENT           SYMENT
2295
#   if defined (C_WEAKEXT)
2296
#     define GCC_OK_SYMBOL(X) \
2297
       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2298
        ((X).n_scnum > N_UNDEF) && \
2299
        (aix64_flag \
2300
         || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2301
             || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2302
#     define GCC_UNDEF_SYMBOL(X) \
2303
       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2304
        ((X).n_scnum == N_UNDEF))
2305
#   else
2306
#     define GCC_OK_SYMBOL(X) \
2307
       (((X).n_sclass == C_EXT) && \
2308
        ((X).n_scnum > N_UNDEF) && \
2309
        (aix64_flag \
2310
         || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2311
             || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2312
#     define GCC_UNDEF_SYMBOL(X) \
2313
       (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2314
#   endif
2315
#   define GCC_SYMINC(X)        ((X).n_numaux+1)
2316
#   define GCC_SYMZERO(X)       0
2317
 
2318
/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2319
#ifdef _AIX51
2320
#   define GCC_CHECK_HDR(X) \
2321
     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2322
      || (HEADER (X).f_magic == 0767 && aix64_flag))
2323
#else
2324
#   define GCC_CHECK_HDR(X) \
2325
     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2326
      || (HEADER (X).f_magic == 0757 && aix64_flag))
2327
#endif
2328
 
2329
#endif
2330
 
2331
#ifdef COLLECT_EXPORT_LIST
2332
/* Array of standard AIX libraries which should not
2333
   be scanned for ctors/dtors.  */
2334
static const char *const aix_std_libs[] = {
2335
  "/unix",
2336
  "/lib/libc.a",
2337
  "/lib/libm.a",
2338
  "/lib/libc_r.a",
2339
  "/lib/libm_r.a",
2340
  "/usr/lib/libc.a",
2341
  "/usr/lib/libm.a",
2342
  "/usr/lib/libc_r.a",
2343
  "/usr/lib/libm_r.a",
2344
  "/usr/lib/threads/libc.a",
2345
  "/usr/ccs/lib/libc.a",
2346
  "/usr/ccs/lib/libm.a",
2347
  "/usr/ccs/lib/libc_r.a",
2348
  "/usr/ccs/lib/libm_r.a",
2349
  NULL
2350
};
2351
 
2352
/* This function checks the filename and returns 1
2353
   if this name matches the location of a standard AIX library.  */
2354
static int ignore_library (const char *);
2355
static int
2356
ignore_library (const char *name)
2357
{
2358
  const char *const *p = &aix_std_libs[0];
2359
  while (*p++ != NULL)
2360
    if (! strcmp (name, *p)) return 1;
2361
  return 0;
2362
}
2363
#endif /* COLLECT_EXPORT_LIST */
2364
 
2365
#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2366
extern char *ldgetname (LDFILE *, GCC_SYMENT *);
2367
#endif
2368
 
2369
/* COFF version to scan the name list of the loaded program for
2370
   the symbols g++ uses for static constructors and destructors.
2371
 
2372
   The constructor table begins at __CTOR_LIST__ and contains a count
2373
   of the number of pointers (or -1 if the constructors are built in a
2374
   separate section by the linker), followed by the pointers to the
2375
   constructor functions, terminated with a null pointer.  The
2376
   destructor table has the same format, and begins at __DTOR_LIST__.  */
2377
 
2378
static void
2379
scan_prog_file (const char *prog_name, enum pass which_pass)
2380
{
2381
  LDFILE *ldptr = NULL;
2382
  int sym_index, sym_count;
2383
  int is_shared = 0;
2384
 
2385
  if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2386
    return;
2387
 
2388
#ifdef COLLECT_EXPORT_LIST
2389
  /* We do not need scanning for some standard C libraries.  */
2390
  if (which_pass == PASS_FIRST && ignore_library (prog_name))
2391
    return;
2392
 
2393
  /* On AIX we have a loop, because there is not much difference
2394
     between an object and an archive. This trick allows us to
2395
     eliminate scan_libraries() function.  */
2396
  do
2397
    {
2398
#endif
2399
      /* Some platforms (e.g. OSF4) declare ldopen as taking a
2400
         non-const char * filename parameter, even though it will not
2401
         modify that string.  So we must cast away const-ness here,
2402
         which will cause -Wcast-qual to burp.  */
2403
      if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2404
        {
2405
          if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2406
            fatal ("%s: not a COFF file", prog_name);
2407
 
2408
          if (GCC_CHECK_HDR (ldptr))
2409
            {
2410
              sym_count = GCC_SYMBOLS (ldptr);
2411
              sym_index = GCC_SYMZERO (ldptr);
2412
 
2413
#ifdef COLLECT_EXPORT_LIST
2414
              /* Is current archive member a shared object?  */
2415
              is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2416
#endif
2417
 
2418
              while (sym_index < sym_count)
2419
                {
2420
                  GCC_SYMENT symbol;
2421
 
2422
                  if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2423
                    break;
2424
                  sym_index += GCC_SYMINC (symbol);
2425
 
2426
                  if (GCC_OK_SYMBOL (symbol))
2427
                    {
2428
                      char *name;
2429
 
2430
                      if ((name = ldgetname (ldptr, &symbol)) == NULL)
2431
                        continue;               /* Should never happen.  */
2432
 
2433
#ifdef XCOFF_DEBUGGING_INFO
2434
                      /* All AIX function names have a duplicate entry
2435
                         beginning with a dot.  */
2436
                      if (*name == '.')
2437
                        ++name;
2438
#endif
2439
 
2440
                      switch (is_ctor_dtor (name))
2441
                        {
2442
                        case 1:
2443
                          if (! is_shared)
2444
                            add_to_list (&constructors, name);
2445
#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2446
                          if (which_pass == PASS_OBJ)
2447
                            add_to_list (&exports, name);
2448
#endif
2449
                          break;
2450
 
2451
                        case 2:
2452
                          if (! is_shared)
2453
                            add_to_list (&destructors, name);
2454
#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2455
                          if (which_pass == PASS_OBJ)
2456
                            add_to_list (&exports, name);
2457
#endif
2458
                          break;
2459
 
2460
#ifdef COLLECT_EXPORT_LIST
2461
                        case 3:
2462
#ifndef LD_INIT_SWITCH
2463
                          if (is_shared)
2464
                            add_to_list (&constructors, name);
2465
#endif
2466
                          break;
2467
 
2468
                        case 4:
2469
#ifndef LD_INIT_SWITCH
2470
                          if (is_shared)
2471
                            add_to_list (&destructors, name);
2472
#endif
2473
                          break;
2474
#endif
2475
 
2476
                        case 5:
2477
                          if (! is_shared)
2478
                            add_to_list (&frame_tables, name);
2479
#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2480
                          if (which_pass == PASS_OBJ)
2481
                            add_to_list (&exports, name);
2482
#endif
2483
                          break;
2484
 
2485
                        default:        /* not a constructor or destructor */
2486
#ifdef COLLECT_EXPORT_LIST
2487
                          /* Explicitly export all global symbols when
2488
                             building a shared object on AIX, but do not
2489
                             re-export symbols from another shared object
2490
                             and do not export symbols if the user
2491
                             provides an explicit export list.  */
2492
                          if (shared_obj && !is_shared
2493
                              && which_pass == PASS_OBJ && !export_flag)
2494
                            add_to_list (&exports, name);
2495
#endif
2496
                          continue;
2497
                        }
2498
 
2499
                      if (debug)
2500
#if !defined(EXTENDED_COFF)
2501
                        fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2502
                                 symbol.n_scnum, symbol.n_sclass,
2503
                                 (symbol.n_type ? "0" : ""), symbol.n_type,
2504
                                 name);
2505
#else
2506
                        fprintf (stderr,
2507
                                 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2508
                                 symbol.iss, (long) symbol.value, symbol.index, name);
2509
#endif
2510
                    }
2511
                }
2512
            }
2513
#ifdef COLLECT_EXPORT_LIST
2514
          else
2515
            {
2516
              /* If archive contains both 32-bit and 64-bit objects,
2517
                 we want to skip objects in other mode so mismatch normal.  */
2518
              if (debug)
2519
                fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2520
                         prog_name, HEADER (ldptr).f_magic, aix64_flag);
2521
            }
2522
#endif
2523
        }
2524
      else
2525
        {
2526
          fatal ("%s: cannot open as COFF file", prog_name);
2527
        }
2528
#ifdef COLLECT_EXPORT_LIST
2529
      /* On AIX loop continues while there are more members in archive.  */
2530
    }
2531
  while (ldclose (ldptr) == FAILURE);
2532
#else
2533
  /* Otherwise we simply close ldptr.  */
2534
  (void) ldclose(ldptr);
2535
#endif
2536
}
2537
#endif /* OBJECT_FORMAT_COFF */
2538
 
2539
#ifdef COLLECT_EXPORT_LIST
2540
/* Given a library name without "lib" prefix, this function
2541
   returns a full library name including a path.  */
2542
static char *
2543
resolve_lib_name (const char *name)
2544
{
2545
  char *lib_buf;
2546
  int i, j, l = 0;
2547
  /* Library extensions for AIX dynamic linking.  */
2548
  const char * const libexts[2] = {"a", "so"};
2549
 
2550
  for (i = 0; libpaths[i]; i++)
2551
    if (libpaths[i]->max_len > l)
2552
      l = libpaths[i]->max_len;
2553
 
2554
  lib_buf = xmalloc (l + strlen(name) + 10);
2555
 
2556
  for (i = 0; libpaths[i]; i++)
2557
    {
2558
      struct prefix_list *list = libpaths[i]->plist;
2559
      for (; list; list = list->next)
2560
        {
2561
          /* The following lines are needed because path_prefix list
2562
             may contain directories both with trailing '/' and
2563
             without it.  */
2564
          const char *p = "";
2565
          if (list->prefix[strlen(list->prefix)-1] != '/')
2566
            p = "/";
2567
          for (j = 0; j < 2; j++)
2568
            {
2569
              sprintf (lib_buf, "%s%slib%s.%s",
2570
                       list->prefix, p, name,
2571
                       libexts[(j + aixrtl_flag) % 2]);
2572
              if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2573
              if (file_exists (lib_buf))
2574
                {
2575
                  if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2576
                  return (lib_buf);
2577
                }
2578
            }
2579
        }
2580
    }
2581
  if (debug)
2582
    fprintf (stderr, "not found\n");
2583
  else
2584
    fatal ("library lib%s not found", name);
2585
  return (NULL);
2586
}
2587
#endif /* COLLECT_EXPORT_LIST */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.