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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [collect2.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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