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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [lto-wrapper.c] - Blame information for rev 867

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

Line No. Rev Author Line
1 684 jeremybenn
/* Wrapper to call lto.  Used by collect2 and the linker plugin.
2
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3
 
4
   Factored out of collect2 by Rafael Espindola <espindola@google.com>
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
 
23
/* This program is passed a gcc, a list of gcc arguments and a list of
24
   object files containing IL. It scans the argument list to check if
25
   we are in whopr mode or not modifies the arguments and needed and
26
   prints a list of output files on stdout.
27
 
28
   Example:
29
 
30
   $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
31
 
32
   The above will print something like
33
   /tmp/ccwbQ8B2.lto.o
34
 
35
   If WHOPR is used instead, more than one file might be produced
36
   ./ccXj2DTk.lto.ltrans.o
37
   ./ccCJuXGv.lto.ltrans.o
38
*/
39
 
40
#include "config.h"
41
#include "system.h"
42
#include "coretypes.h"
43
#include "intl.h"
44
#include "diagnostic.h"
45
#include "obstack.h"
46
#include "opts.h"
47
#include "options.h"
48
#include "simple-object.h"
49
 
50
/* From lto-streamer.h which we cannot include with -fkeep-inline-functions.
51
   ???  Split out a lto-streamer-core.h.  */
52
 
53
#define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
54
 
55
/* End of lto-streamer.h copy.  */
56
 
57
int debug;                              /* true if -save-temps.  */
58
int verbose;                            /* true if -v.  */
59
 
60
enum lto_mode_d {
61
  LTO_MODE_NONE,                        /* Not doing LTO.  */
62
  LTO_MODE_LTO,                         /* Normal LTO.  */
63
  LTO_MODE_WHOPR                        /* WHOPR.  */
64
};
65
 
66
/* Current LTO mode.  */
67
static enum lto_mode_d lto_mode = LTO_MODE_NONE;
68
 
69
static char *ltrans_output_file;
70
static char *flto_out;
71
static char *args_name;
72
static unsigned int nr;
73
static char **input_names;
74
static char **output_names;
75
static char *makefile;
76
 
77
static void maybe_unlink_file (const char *);
78
 
79
 /* Delete tempfiles.  */
80
 
81
static void
82
lto_wrapper_cleanup (void)
83
{
84
  static bool cleanup_done = false;
85
  unsigned int i;
86
 
87
  if (cleanup_done)
88
    return;
89
 
90
  /* Setting cleanup_done prevents an infinite loop if one of the
91
     calls to maybe_unlink_file fails. */
92
  cleanup_done = true;
93
 
94
  if (ltrans_output_file)
95
    maybe_unlink_file (ltrans_output_file);
96
  if (flto_out)
97
    maybe_unlink_file (flto_out);
98
  if (args_name)
99
    maybe_unlink_file (args_name);
100
  if (makefile)
101
    maybe_unlink_file (makefile);
102
  for (i = 0; i < nr; ++i)
103
    {
104
      maybe_unlink_file (input_names[i]);
105
      if (output_names[i])
106
        maybe_unlink_file (output_names[i]);
107
    }
108
}
109
 
110
static void
111
fatal_signal (int signum)
112
{
113
  signal (signum, SIG_DFL);
114
  lto_wrapper_cleanup ();
115
  /* Get the same signal again, this time not handled,
116
     so its normal effect occurs.  */
117
  kill (getpid (), signum);
118
}
119
 
120
/* Just die. CMSGID is the error message. */
121
 
122
static void __attribute__ ((format (printf, 1, 2)))
123
fatal (const char * cmsgid, ...)
124
{
125
  va_list ap;
126
 
127
  va_start (ap, cmsgid);
128
  fprintf (stderr, "lto-wrapper: ");
129
  vfprintf (stderr, _(cmsgid), ap);
130
  fprintf (stderr, "\n");
131
  va_end (ap);
132
 
133
  lto_wrapper_cleanup ();
134
  exit (FATAL_EXIT_CODE);
135
}
136
 
137
 
138
/* Die when sys call fails. CMSGID is the error message.  */
139
 
140
static void __attribute__ ((format (printf, 1, 2)))
141
fatal_perror (const char *cmsgid, ...)
142
{
143
  int e = errno;
144
  va_list ap;
145
 
146
  va_start (ap, cmsgid);
147
  fprintf (stderr, "lto-wrapper: ");
148
  vfprintf (stderr, _(cmsgid), ap);
149
  fprintf (stderr, ": %s\n", xstrerror (e));
150
  va_end (ap);
151
 
152
  lto_wrapper_cleanup ();
153
  exit (FATAL_EXIT_CODE);
154
}
155
 
156
 
157
/* Execute a program, and wait for the reply. ARGV are the arguments. The
158
   last one must be NULL. */
159
 
160
static struct pex_obj *
161
collect_execute (char **argv)
162
{
163
  struct pex_obj *pex;
164
  const char *errmsg;
165
  int err;
166
 
167
  if (verbose)
168
    {
169
      char **p_argv;
170
      const char *str;
171
 
172
      for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
173
        fprintf (stderr, " %s", str);
174
 
175
      fprintf (stderr, "\n");
176
    }
177
 
178
  fflush (stdout);
179
  fflush (stderr);
180
 
181
  pex = pex_init (0, "lto-wrapper", NULL);
182
  if (pex == NULL)
183
    fatal_perror ("pex_init failed");
184
 
185
  /* Do not use PEX_LAST here, we use our stdout for communicating with
186
     collect2 or the linker-plugin.  Any output from the sub-process
187
     will confuse that.  */
188
  errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
189
                    NULL, &err);
190
  if (errmsg != NULL)
191
    {
192
      if (err != 0)
193
        {
194
          errno = err;
195
          fatal_perror (errmsg);
196
        }
197
      else
198
        fatal (errmsg);
199
    }
200
 
201
  return pex;
202
}
203
 
204
 
205
/* Wait for a process to finish, and exit if a nonzero status is found.
206
   PROG is the program name. PEX is the process we should wait for. */
207
 
208
static int
209
collect_wait (const char *prog, struct pex_obj *pex)
210
{
211
  int status;
212
 
213
  if (!pex_get_status (pex, 1, &status))
214
    fatal_perror ("can't get program status");
215
  pex_free (pex);
216
 
217
  if (status)
218
    {
219
      if (WIFSIGNALED (status))
220
        {
221
          int sig = WTERMSIG (status);
222
          if (WCOREDUMP (status))
223
            fatal ("%s terminated with signal %d [%s], core dumped",
224
                   prog, sig, strsignal (sig));
225
          else
226
            fatal ("%s terminated with signal %d [%s]",
227
                   prog, sig, strsignal (sig));
228
        }
229
 
230
      if (WIFEXITED (status))
231
        fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
232
    }
233
 
234
  return 0;
235
}
236
 
237
 
238
/* Unlink a temporary LTRANS file unless requested otherwise.  */
239
 
240
static void
241
maybe_unlink_file (const char *file)
242
{
243
  if (! debug)
244
    {
245
      if (unlink_if_ordinary (file)
246
          && errno != ENOENT)
247
        fatal_perror ("deleting LTRANS file %s", file);
248
    }
249
  else
250
    fprintf (stderr, "[Leaving LTRANS %s]\n", file);
251
}
252
 
253
 
254
/* Execute program ARGV[0] with arguments ARGV. Wait for it to finish.  */
255
 
256
static void
257
fork_execute (char **argv)
258
{
259
  struct pex_obj *pex;
260
  char *new_argv[3];
261
  char *at_args;
262
  FILE *args;
263
  int status;
264
 
265
  args_name = make_temp_file (".args");
266
  at_args = concat ("@", args_name, NULL);
267
  args = fopen (args_name, "w");
268
  if (args == NULL)
269
    fatal ("failed to open %s", args_name);
270
 
271
  status = writeargv (&argv[1], args);
272
 
273
  if (status)
274
    fatal ("could not write to temporary file %s",  args_name);
275
 
276
  fclose (args);
277
 
278
  new_argv[0] = argv[0];
279
  new_argv[1] = at_args;
280
  new_argv[2] = NULL;
281
 
282
  pex = collect_execute (new_argv);
283
  collect_wait (new_argv[0], pex);
284
 
285
  maybe_unlink_file (args_name);
286
  args_name = NULL;
287
  free (at_args);
288
}
289
 
290
/* Template of LTRANS dumpbase suffix.  */
291
#define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
292
 
293
/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
294
   environment according to LANG_MASK.  */
295
 
296
static void
297
get_options_from_collect_gcc_options (const char *collect_gcc,
298
                                      const char *collect_gcc_options,
299
                                      unsigned int lang_mask,
300
                                      struct cl_decoded_option **decoded_options,
301
                                      unsigned int *decoded_options_count)
302
{
303
  struct obstack argv_obstack;
304
  char *argv_storage;
305
  const char **argv;
306
  int j, k, argc;
307
 
308
  argv_storage = xstrdup (collect_gcc_options);
309
  obstack_init (&argv_obstack);
310
  obstack_ptr_grow (&argv_obstack, collect_gcc);
311
 
312
  for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
313
    {
314
      if (argv_storage[j] == '\'')
315
        {
316
          obstack_ptr_grow (&argv_obstack, &argv_storage[k]);
317
          ++j;
318
          do
319
            {
320
              if (argv_storage[j] == '\0')
321
                fatal ("malformed COLLECT_GCC_OPTIONS");
322
              else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
323
                {
324
                  argv_storage[k++] = '\'';
325
                  j += 4;
326
                }
327
              else if (argv_storage[j] == '\'')
328
                break;
329
              else
330
                argv_storage[k++] = argv_storage[j++];
331
            }
332
          while (1);
333
          argv_storage[k++] = '\0';
334
        }
335
    }
336
 
337
  obstack_ptr_grow (&argv_obstack, NULL);
338
  argc = obstack_object_size (&argv_obstack) / sizeof (void *) - 1;
339
  argv = XOBFINISH (&argv_obstack, const char **);
340
 
341
  decode_cmdline_options_to_array (argc, (const char **)argv,
342
                                   lang_mask,
343
                                   decoded_options, decoded_options_count);
344
  obstack_free (&argv_obstack, NULL);
345
}
346
 
347
/* Append OPTION to the options array DECODED_OPTIONS with size
348
   DECODED_OPTIONS_COUNT.  */
349
 
350
static void
351
append_option (struct cl_decoded_option **decoded_options,
352
               unsigned int *decoded_options_count,
353
               struct cl_decoded_option *option)
354
{
355
  ++*decoded_options_count;
356
  *decoded_options
357
    = (struct cl_decoded_option *)
358
        xrealloc (*decoded_options,
359
                  (*decoded_options_count
360
                   * sizeof (struct cl_decoded_option)));
361
  memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
362
          sizeof (struct cl_decoded_option));
363
}
364
 
365
/* Try to merge and complain about options FDECODED_OPTIONS when applied
366
   ontop of DECODED_OPTIONS.  */
367
 
368
static void
369
merge_and_complain (struct cl_decoded_option **decoded_options,
370
                    unsigned int *decoded_options_count,
371
                    struct cl_decoded_option *fdecoded_options,
372
                    unsigned int fdecoded_options_count)
373
{
374
  unsigned int i, j;
375
 
376
  /* ???  Merge options from files.  Most cases can be
377
     handled by either unioning or intersecting
378
     (for example -fwrapv is a case for unioning,
379
     -ffast-math is for intersection).  Most complaints
380
     about real conflicts between different options can
381
     be deferred to the compiler proper.  Options that
382
     we can neither safely handle by intersection nor
383
     unioning would need to be complained about here.
384
     Ideally we'd have a flag in the opt files that
385
     tells whether to union or intersect or reject.
386
     In absence of that it's unclear what a good default is.
387
     It's also difficult to get positional handling correct.  */
388
 
389
  /* The following does what the old LTO option code did,
390
     union all target and a selected set of common options.  */
391
  for (i = 0; i < fdecoded_options_count; ++i)
392
    {
393
      struct cl_decoded_option *foption = &fdecoded_options[i];
394
      switch (foption->opt_index)
395
        {
396
        default:
397
          if (!(cl_options[foption->opt_index].flags & CL_TARGET))
398
            break;
399
 
400
          /* Fallthru.  */
401
        case OPT_fPIC:
402
        case OPT_fpic:
403
        case OPT_fpie:
404
        case OPT_fcommon:
405
        case OPT_fexceptions:
406
        case OPT_fgnu_tm:
407
          /* Do what the old LTO code did - collect exactly one option
408
             setting per OPT code, we pick the first we encounter.
409
             ???  This doesn't make too much sense, but when it doesn't
410
             then we should complain.  */
411
          for (j = 0; j < *decoded_options_count; ++j)
412
            if ((*decoded_options)[j].opt_index == foption->opt_index)
413
              break;
414
          if (j == *decoded_options_count)
415
            append_option (decoded_options, decoded_options_count, foption);
416
          break;
417
        }
418
    }
419
}
420
 
421
/* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
422
 
423
static void
424
run_gcc (unsigned argc, char *argv[])
425
{
426
  unsigned i, j;
427
  const char **new_argv;
428
  const char **argv_ptr;
429
  char *list_option_full = NULL;
430
  const char *linker_output = NULL;
431
  const char *collect_gcc, *collect_gcc_options;
432
  int parallel = 0;
433
  int jobserver = 0;
434
  bool no_partition = false;
435
  struct cl_decoded_option *fdecoded_options = NULL;
436
  unsigned int fdecoded_options_count = 0;
437
  struct cl_decoded_option *decoded_options;
438
  unsigned int decoded_options_count;
439
  struct obstack argv_obstack;
440
  int new_head_argc;
441
 
442
  /* Get the driver and options.  */
443
  collect_gcc = getenv ("COLLECT_GCC");
444
  if (!collect_gcc)
445
    fatal ("environment variable COLLECT_GCC must be set");
446
  collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
447
  if (!collect_gcc_options)
448
    fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
449
  get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
450
                                        CL_LANG_ALL,
451
                                        &decoded_options,
452
                                        &decoded_options_count);
453
 
454
  /* Look at saved options in the IL files.  */
455
  for (i = 1; i < argc; ++i)
456
    {
457
      char *data, *p;
458
      char *fopts;
459
      int fd;
460
      const char *errmsg;
461
      int err;
462
      off_t file_offset = 0, offset, length;
463
      long loffset;
464
      simple_object_read *sobj;
465
      int consumed;
466
      struct cl_decoded_option *f2decoded_options;
467
      unsigned int f2decoded_options_count;
468
      char *filename = argv[i];
469
      if ((p = strrchr (argv[i], '@'))
470
          && p != argv[i]
471
          && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
472
          && strlen (p) == (unsigned int) consumed)
473
        {
474
          filename = XNEWVEC (char, p - argv[i] + 1);
475
          memcpy (filename, argv[i], p - argv[i]);
476
          filename[p - argv[i]] = '\0';
477
          file_offset = (off_t) loffset;
478
        }
479
      fd = open (argv[i], O_RDONLY);
480
      if (fd == -1)
481
        continue;
482
      sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
483
                                       &errmsg, &err);
484
      if (!sobj)
485
        {
486
          close (fd);
487
          continue;
488
        }
489
      if (!simple_object_find_section (sobj, LTO_SECTION_NAME_PREFIX "." "opts",
490
                                       &offset, &length, &errmsg, &err))
491
        {
492
          simple_object_release_read (sobj);
493
          close (fd);
494
          continue;
495
        }
496
      lseek (fd, file_offset + offset, SEEK_SET);
497
      data = (char *)xmalloc (length);
498
      read (fd, data, length);
499
      fopts = data;
500
      do
501
        {
502
          get_options_from_collect_gcc_options (collect_gcc,
503
                                                fopts, CL_LANG_ALL,
504
                                                &f2decoded_options,
505
                                                &f2decoded_options_count);
506
          if (!fdecoded_options)
507
            {
508
              fdecoded_options = f2decoded_options;
509
              fdecoded_options_count = f2decoded_options_count;
510
            }
511
          else
512
            merge_and_complain (&fdecoded_options,
513
                                &fdecoded_options_count,
514
                                f2decoded_options, f2decoded_options_count);
515
 
516
          fopts += strlen (fopts) + 1;
517
        }
518
      while (fopts - data < length);
519
 
520
      free (data);
521
      simple_object_release_read (sobj);
522
      close (fd);
523
    }
524
 
525
  /* Initalize the common arguments for the driver.  */
526
  obstack_init (&argv_obstack);
527
  obstack_ptr_grow (&argv_obstack, collect_gcc);
528
  obstack_ptr_grow (&argv_obstack, "-xlto");
529
  obstack_ptr_grow (&argv_obstack, "-c");
530
 
531
  /* Append compiler driver arguments as far as they were merged.  */
532
  for (j = 1; j < fdecoded_options_count; ++j)
533
    {
534
      struct cl_decoded_option *option = &fdecoded_options[j];
535
 
536
      /* File options have been properly filtered by lto-opts.c.  */
537
      switch (option->opt_index)
538
        {
539
          /* Drop arguments that we want to take from the link line.  */
540
          case OPT_flto_:
541
          case OPT_flto:
542
          case OPT_flto_partition_none:
543
          case OPT_flto_partition_1to1:
544
          case OPT_flto_partition_balanced:
545
              continue;
546
 
547
          default:
548
              break;
549
        }
550
 
551
      /* For now do what the original LTO option code was doing - pass
552
         on any CL_TARGET flag and a few selected others.  */
553
      switch (option->opt_index)
554
        {
555
        case OPT_fPIC:
556
        case OPT_fpic:
557
        case OPT_fpie:
558
        case OPT_fcommon:
559
        case OPT_fexceptions:
560
        case OPT_fgnu_tm:
561
          break;
562
 
563
        default:
564
          if (!(cl_options[option->opt_index].flags & CL_TARGET))
565
            continue;
566
        }
567
 
568
      /* Pass the option on.  */
569
      for (i = 0; i < option->canonical_option_num_elements; ++i)
570
        obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
571
    }
572
 
573
  /* Append linker driver arguments.  Compiler options from the linker
574
     driver arguments will override / merge with those from the compiler.  */
575
  for (j = 1; j < decoded_options_count; ++j)
576
    {
577
      struct cl_decoded_option *option = &decoded_options[j];
578
 
579
      /* Do not pass on frontend specific flags not suitable for lto.  */
580
      if (!(cl_options[option->opt_index].flags
581
            & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
582
        continue;
583
 
584
      switch (option->opt_index)
585
        {
586
        case OPT_o:
587
          linker_output = option->arg;
588
          /* We generate new intermediate output, drop this arg.  */
589
          continue;
590
 
591
        case OPT_save_temps:
592
          debug = 1;
593
          break;
594
 
595
        case OPT_v:
596
          verbose = 1;
597
          break;
598
 
599
        case OPT_flto_partition_none:
600
          no_partition = true;
601
          break;
602
 
603
        case OPT_flto_:
604
          if (strcmp (option->arg, "jobserver") == 0)
605
            {
606
              jobserver = 1;
607
              parallel = 1;
608
            }
609
          else
610
            {
611
              parallel = atoi (option->arg);
612
              if (parallel <= 1)
613
                parallel = 0;
614
            }
615
          /* Fallthru.  */
616
 
617
        case OPT_flto:
618
          lto_mode = LTO_MODE_WHOPR;
619
          /* We've handled these LTO options, do not pass them on.  */
620
          continue;
621
 
622
        default:
623
          break;
624
        }
625
 
626
      /* Pass the option on.  */
627
      for (i = 0; i < option->canonical_option_num_elements; ++i)
628
        obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
629
    }
630
 
631
  if (no_partition)
632
    {
633
      lto_mode = LTO_MODE_LTO;
634
      jobserver = 0;
635
      parallel = 0;
636
    }
637
 
638
  if (linker_output)
639
    {
640
      char *output_dir, *base, *name;
641
      bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0;
642
 
643
      output_dir = xstrdup (linker_output);
644
      base = output_dir;
645
      for (name = base; *name; name++)
646
        if (IS_DIR_SEPARATOR (*name))
647
          base = name + 1;
648
      *base = '\0';
649
 
650
      linker_output = &linker_output[base - output_dir];
651
      if (*output_dir == '\0')
652
        {
653
          static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
654
          output_dir = current_dir;
655
        }
656
      if (!bit_bucket)
657
        {
658
          obstack_ptr_grow (&argv_obstack, "-dumpdir");
659
          obstack_ptr_grow (&argv_obstack, output_dir);
660
        }
661
 
662
      obstack_ptr_grow (&argv_obstack, "-dumpbase");
663
    }
664
 
665
  /* Remember at which point we can scrub args to re-use the commons.  */
666
  new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
667
 
668
  if (lto_mode == LTO_MODE_LTO)
669
    {
670
      flto_out = make_temp_file (".lto.o");
671
      if (linker_output)
672
        obstack_ptr_grow (&argv_obstack, linker_output);
673
      obstack_ptr_grow (&argv_obstack, "-o");
674
      obstack_ptr_grow (&argv_obstack, flto_out);
675
    }
676
  else
677
    {
678
      const char *list_option = "-fltrans-output-list=";
679
      size_t list_option_len = strlen (list_option);
680
      char *tmp;
681
 
682
      if (linker_output)
683
        {
684
          char *dumpbase = (char *) xmalloc (strlen (linker_output)
685
                                             + sizeof (".wpa") + 1);
686
          strcpy (dumpbase, linker_output);
687
          strcat (dumpbase, ".wpa");
688
          obstack_ptr_grow (&argv_obstack, dumpbase);
689
        }
690
 
691
      if (linker_output && debug)
692
        {
693
          ltrans_output_file = (char *) xmalloc (strlen (linker_output)
694
                                                 + sizeof (".ltrans.out") + 1);
695
          strcpy (ltrans_output_file, linker_output);
696
          strcat (ltrans_output_file, ".ltrans.out");
697
        }
698
      else
699
        ltrans_output_file = make_temp_file (".ltrans.out");
700
      list_option_full = (char *) xmalloc (sizeof (char) *
701
                         (strlen (ltrans_output_file) + list_option_len + 1));
702
      tmp = list_option_full;
703
 
704
      obstack_ptr_grow (&argv_obstack, tmp);
705
      strcpy (tmp, list_option);
706
      tmp += list_option_len;
707
      strcpy (tmp, ltrans_output_file);
708
 
709
      obstack_ptr_grow (&argv_obstack, "-fwpa");
710
    }
711
 
712
  /* Append the input objects and possible preceeding arguments.  */
713
  for (i = 1; i < argc; ++i)
714
    obstack_ptr_grow (&argv_obstack, argv[i]);
715
  obstack_ptr_grow (&argv_obstack, NULL);
716
 
717
  new_argv = XOBFINISH (&argv_obstack, const char **);
718
  argv_ptr = &new_argv[new_head_argc];
719
  fork_execute (CONST_CAST (char **, new_argv));
720
 
721
  if (lto_mode == LTO_MODE_LTO)
722
    {
723
      printf("%s\n", flto_out);
724
      free (flto_out);
725
      flto_out = NULL;
726
    }
727
  else
728
    {
729
      FILE *stream = fopen (ltrans_output_file, "r");
730
      FILE *mstream = NULL;
731
      struct obstack env_obstack;
732
 
733
      if (!stream)
734
        fatal_perror ("fopen: %s", ltrans_output_file);
735
 
736
      /* Parse the list of LTRANS inputs from the WPA stage.  */
737
      obstack_init (&env_obstack);
738
      nr = 0;
739
      for (;;)
740
        {
741
          const unsigned piece = 32;
742
          char *output_name = NULL;
743
          char *buf, *input_name = (char *)xmalloc (piece);
744
          size_t len;
745
 
746
          buf = input_name;
747
cont:
748
          if (!fgets (buf, piece, stream))
749
            break;
750
          len = strlen (input_name);
751
          if (input_name[len - 1] != '\n')
752
            {
753
              input_name = (char *)xrealloc (input_name, len + piece);
754
              buf = input_name + len;
755
              goto cont;
756
            }
757
          input_name[len - 1] = '\0';
758
 
759
          if (input_name[0] == '*')
760
            output_name = &input_name[1];
761
 
762
          nr++;
763
          input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
764
          output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
765
          input_names[nr-1] = input_name;
766
          output_names[nr-1] = output_name;
767
        }
768
      fclose (stream);
769
      maybe_unlink_file (ltrans_output_file);
770
      ltrans_output_file = NULL;
771
 
772
      if (parallel)
773
        {
774
          makefile = make_temp_file (".mk");
775
          mstream = fopen (makefile, "w");
776
        }
777
 
778
      /* Execute the LTRANS stage for each input file (or prepare a
779
         makefile to invoke this in parallel).  */
780
      for (i = 0; i < nr; ++i)
781
        {
782
          char *output_name;
783
          char *input_name = input_names[i];
784
          /* If it's a pass-through file do nothing.  */
785
          if (output_names[i])
786
            continue;
787
 
788
          /* Replace the .o suffix with a .ltrans.o suffix and write
789
             the resulting name to the LTRANS output list.  */
790
          obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
791
          obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
792
          output_name = XOBFINISH (&env_obstack, char *);
793
 
794
          /* Adjust the dumpbase if the linker output file was seen.  */
795
          if (linker_output)
796
            {
797
              char *dumpbase
798
                  = (char *) xmalloc (strlen (linker_output)
799
                                      + sizeof(DUMPBASE_SUFFIX) + 1);
800
              snprintf (dumpbase,
801
                        strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
802
                        "%s.ltrans%u", linker_output, i);
803
              argv_ptr[0] = dumpbase;
804
            }
805
 
806
          argv_ptr[1] = "-fltrans";
807
          argv_ptr[2] = "-o";
808
          argv_ptr[3] = output_name;
809
          argv_ptr[4] = input_name;
810
          argv_ptr[5] = NULL;
811
          if (parallel)
812
            {
813
              fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
814
              for (j = 1; new_argv[j] != NULL; ++j)
815
                fprintf (mstream, " '%s'", new_argv[j]);
816
              fprintf (mstream, "\n");
817
              /* If we are not preserving the ltrans input files then
818
                 truncate them as soon as we have processed it.  This
819
                 reduces temporary disk-space usage.  */
820
              if (! debug)
821
                fprintf (mstream, "\t@-touch -r %s %s.tem > /dev/null 2>&1 "
822
                         "&& mv %s.tem %s\n",
823
                         input_name, input_name, input_name, input_name);
824
            }
825
          else
826
            {
827
              fork_execute (CONST_CAST (char **, new_argv));
828
              maybe_unlink_file (input_name);
829
            }
830
 
831
          output_names[i] = output_name;
832
        }
833
      if (parallel)
834
        {
835
          struct pex_obj *pex;
836
          char jobs[32];
837
 
838
          fprintf (mstream, "all:");
839
          for (i = 0; i < nr; ++i)
840
            fprintf (mstream, " \\\n\t%s", output_names[i]);
841
          fprintf (mstream, "\n");
842
          fclose (mstream);
843
          if (!jobserver)
844
            {
845
              /* Avoid passing --jobserver-fd= and similar flags
846
                 unless jobserver mode is explicitly enabled.  */
847
              putenv (xstrdup ("MAKEFLAGS="));
848
              putenv (xstrdup ("MFLAGS="));
849
            }
850
          new_argv[0] = getenv ("MAKE");
851
          if (!new_argv[0])
852
            new_argv[0] = "make";
853
          new_argv[1] = "-f";
854
          new_argv[2] = makefile;
855
          i = 3;
856
          if (!jobserver)
857
            {
858
              snprintf (jobs, 31, "-j%d", parallel);
859
              new_argv[i++] = jobs;
860
            }
861
          new_argv[i++] = "all";
862
          new_argv[i++] = NULL;
863
          pex = collect_execute (CONST_CAST (char **, new_argv));
864
          collect_wait (new_argv[0], pex);
865
          maybe_unlink_file (makefile);
866
          makefile = NULL;
867
          for (i = 0; i < nr; ++i)
868
            maybe_unlink_file (input_names[i]);
869
        }
870
      for (i = 0; i < nr; ++i)
871
        {
872
          fputs (output_names[i], stdout);
873
          putc ('\n', stdout);
874
          free (input_names[i]);
875
        }
876
      nr = 0;
877
      free (output_names);
878
      free (input_names);
879
      free (list_option_full);
880
      obstack_free (&env_obstack, NULL);
881
    }
882
 
883
  obstack_free (&argv_obstack, NULL);
884
}
885
 
886
 
887
/* Entry point.  */
888
 
889
int
890
main (int argc, char *argv[])
891
{
892
  const char *p;
893
 
894
  p = argv[0] + strlen (argv[0]);
895
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
896
    --p;
897
  progname = p;
898
 
899
  xmalloc_set_program_name (progname);
900
 
901
  gcc_init_libintl ();
902
 
903
  diagnostic_initialize (global_dc, 0);
904
 
905
  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
906
    signal (SIGINT, fatal_signal);
907
#ifdef SIGHUP
908
  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
909
    signal (SIGHUP, fatal_signal);
910
#endif
911
  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
912
    signal (SIGTERM, fatal_signal);
913
#ifdef SIGPIPE
914
  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
915
    signal (SIGPIPE, fatal_signal);
916
#endif
917
#ifdef SIGCHLD
918
  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
919
     receive the signal.  A different setting is inheritable */
920
  signal (SIGCHLD, SIG_DFL);
921
#endif
922
 
923
  /* We may be called with all the arguments stored in some file and
924
     passed with @file.  Expand them into argv before processing.  */
925
  expandargv (&argc, &argv);
926
 
927
  run_gcc (argc, argv);
928
 
929
  return 0;
930
}

powered by: WebSVN 2.1.0

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