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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [tlink.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
/* Scan linker error messages for missing template instantiations and provide
2
   them.
3
 
4
   Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008,
5
   2009, 2010, 2011 Free Software Foundation, Inc.
6
   Contributed by Jason Merrill (jason@cygnus.com).
7
 
8
This file is part of GCC.
9
 
10
GCC is free software; you can redistribute it and/or modify it under
11
the terms of the GNU General Public License as published by the Free
12
Software Foundation; either version 3, or (at your option) any later
13
version.
14
 
15
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16
WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18
for more details.
19
 
20
You should have received a copy of the GNU General Public License
21
along with GCC; see the file COPYING3.  If not see
22
<http://www.gnu.org/licenses/>.  */
23
 
24
#include "config.h"
25
#include "system.h"
26
#include "coretypes.h"
27
#include "tm.h"
28
#include "intl.h"
29
#include "obstack.h"
30
#include "hashtab.h"
31
#include "demangle.h"
32
#include "collect2.h"
33
#include "filenames.h"
34
#include "diagnostic-core.h"
35
#include "vec.h"
36
 
37
/* TARGET_64BIT may be defined to use driver specific functionality. */
38
#undef TARGET_64BIT
39
#define TARGET_64BIT TARGET_64BIT_DEFAULT
40
 
41
#define MAX_ITERATIONS 17
42
 
43
/* Defined in the automatically-generated underscore.c.  */
44
extern int prepends_underscore;
45
 
46
static int tlink_verbose;
47
 
48
static char *initial_cwd;
49
 
50
/* Hash table boilerplate for working with htab_t.  We have hash tables
51
   for symbol names, file names, and demangled symbols.  */
52
 
53
typedef struct symbol_hash_entry
54
{
55
  const char *key;
56
  struct file_hash_entry *file;
57
  int chosen;
58
  int tweaking;
59
  int tweaked;
60
} symbol;
61
 
62
typedef struct file_hash_entry
63
{
64
  const char *key;
65
  const char *args;
66
  const char *dir;
67
  const char *main;
68
  int tweaking;
69
} file;
70
 
71
typedef const char *str;
72
DEF_VEC_P(str);
73
DEF_VEC_ALLOC_P(str,heap);
74
 
75
typedef struct demangled_hash_entry
76
{
77
  const char *key;
78
  VEC(str,heap) *mangled;
79
} demangled;
80
 
81
/* Hash and comparison functions for these hash tables.  */
82
 
83
static int hash_string_eq (const void *, const void *);
84
static hashval_t hash_string_hash (const void *);
85
 
86
static int
87
hash_string_eq (const void *s1_p, const void *s2_p)
88
{
89
  const char *const *s1 = (const char *const *) s1_p;
90
  const char *s2 = (const char *) s2_p;
91
  return strcmp (*s1, s2) == 0;
92
}
93
 
94
static hashval_t
95
hash_string_hash (const void *s_p)
96
{
97
  const char *const *s = (const char *const *) s_p;
98
  return (*htab_hash_string) (*s);
99
}
100
 
101
static htab_t symbol_table;
102
 
103
static struct symbol_hash_entry * symbol_hash_lookup (const char *, int);
104
static struct file_hash_entry * file_hash_lookup (const char *);
105
static struct demangled_hash_entry *demangled_hash_lookup (const char *, int);
106
static void symbol_push (symbol *);
107
static symbol * symbol_pop (void);
108
static void file_push (file *);
109
static file * file_pop (void);
110
static void tlink_init (void);
111
static int tlink_execute (const char *, char **, const char *, const char *);
112
static char * frob_extension (const char *, const char *);
113
static char * obstack_fgets (FILE *, struct obstack *);
114
static char * tfgets (FILE *);
115
static char * pfgets (FILE *);
116
static void freadsym (FILE *, file *, int);
117
static void read_repo_file (file *);
118
static void maybe_tweak (char *, file *);
119
static int recompile_files (void);
120
static int read_repo_files (char **);
121
static void demangle_new_symbols (void);
122
static int scan_linker_output (const char *);
123
 
124
/* Look up an entry in the symbol hash table.  */
125
 
126
static struct symbol_hash_entry *
127
symbol_hash_lookup (const char *string, int create)
128
{
129
  void **e;
130
  e = htab_find_slot_with_hash (symbol_table, string,
131
                                (*htab_hash_string) (string),
132
                                create ? INSERT : NO_INSERT);
133
  if (e == NULL)
134
    return NULL;
135
  if (*e == NULL)
136
    {
137
      struct symbol_hash_entry *v;
138
      *e = v = XCNEW (struct symbol_hash_entry);
139
      v->key = xstrdup (string);
140
    }
141
  return (struct symbol_hash_entry *) *e;
142
}
143
 
144
static htab_t file_table;
145
 
146
/* Look up an entry in the file hash table.  */
147
 
148
static struct file_hash_entry *
149
file_hash_lookup (const char *string)
150
{
151
  void **e;
152
  e = htab_find_slot_with_hash (file_table, string,
153
                                (*htab_hash_string) (string),
154
                                INSERT);
155
  if (*e == NULL)
156
    {
157
      struct file_hash_entry *v;
158
      *e = v = XCNEW (struct file_hash_entry);
159
      v->key = xstrdup (string);
160
    }
161
  return (struct file_hash_entry *) *e;
162
}
163
 
164
static htab_t demangled_table;
165
 
166
/* Look up an entry in the demangled name hash table.  */
167
 
168
static struct demangled_hash_entry *
169
demangled_hash_lookup (const char *string, int create)
170
{
171
  void **e;
172
  e = htab_find_slot_with_hash (demangled_table, string,
173
                                (*htab_hash_string) (string),
174
                                create ? INSERT : NO_INSERT);
175
  if (e == NULL)
176
    return NULL;
177
  if (*e == NULL)
178
    {
179
      struct demangled_hash_entry *v;
180
      *e = v = XCNEW (struct demangled_hash_entry);
181
      v->key = xstrdup (string);
182
    }
183
  return (struct demangled_hash_entry *) *e;
184
}
185
 
186
/* Stack code.  */
187
 
188
struct symbol_stack_entry
189
{
190
  symbol *value;
191
  struct symbol_stack_entry *next;
192
};
193
struct obstack symbol_stack_obstack;
194
struct symbol_stack_entry *symbol_stack;
195
 
196
struct file_stack_entry
197
{
198
  file *value;
199
  struct file_stack_entry *next;
200
};
201
struct obstack file_stack_obstack;
202
struct file_stack_entry *file_stack;
203
 
204
static void
205
symbol_push (symbol *p)
206
{
207
  struct symbol_stack_entry *ep
208
    = XOBNEW (&symbol_stack_obstack, struct symbol_stack_entry);
209
  ep->value = p;
210
  ep->next = symbol_stack;
211
  symbol_stack = ep;
212
}
213
 
214
static symbol *
215
symbol_pop (void)
216
{
217
  struct symbol_stack_entry *ep = symbol_stack;
218
  symbol *p;
219
  if (ep == NULL)
220
    return NULL;
221
  p = ep->value;
222
  symbol_stack = ep->next;
223
  obstack_free (&symbol_stack_obstack, ep);
224
  return p;
225
}
226
 
227
static void
228
file_push (file *p)
229
{
230
  struct file_stack_entry *ep;
231
 
232
  if (p->tweaking)
233
    return;
234
 
235
  ep = XOBNEW (&file_stack_obstack, struct file_stack_entry);
236
  ep->value = p;
237
  ep->next = file_stack;
238
  file_stack = ep;
239
  p->tweaking = 1;
240
}
241
 
242
static file *
243
file_pop (void)
244
{
245
  struct file_stack_entry *ep = file_stack;
246
  file *p;
247
  if (ep == NULL)
248
    return NULL;
249
  p = ep->value;
250
  file_stack = ep->next;
251
  obstack_free (&file_stack_obstack, ep);
252
  p->tweaking = 0;
253
  return p;
254
}
255
 
256
/* Other machinery.  */
257
 
258
/* Initialize the tlink machinery.  Called from do_tlink.  */
259
 
260
static void
261
tlink_init (void)
262
{
263
  const char *p;
264
 
265
  symbol_table = htab_create (500, hash_string_hash, hash_string_eq,
266
                              NULL);
267
  file_table = htab_create (500, hash_string_hash, hash_string_eq,
268
                            NULL);
269
  demangled_table = htab_create (500, hash_string_hash, hash_string_eq,
270
                                 NULL);
271
 
272
  obstack_begin (&symbol_stack_obstack, 0);
273
  obstack_begin (&file_stack_obstack, 0);
274
 
275
  p = getenv ("TLINK_VERBOSE");
276
  if (p)
277
    tlink_verbose = atoi (p);
278
  else
279
    {
280
      tlink_verbose = 1;
281
      if (vflag)
282
        tlink_verbose = 2;
283
      if (debug)
284
        tlink_verbose = 3;
285
    }
286
 
287
  initial_cwd = getpwd ();
288
}
289
 
290
static int
291
tlink_execute (const char *prog, char **argv, const char *outname,
292
               const char *errname)
293
{
294
  struct pex_obj *pex;
295
 
296
  pex = collect_execute (prog, argv, outname, errname, PEX_LAST | PEX_SEARCH);
297
  return collect_wait (prog, pex);
298
}
299
 
300
static char *
301
frob_extension (const char *s, const char *ext)
302
{
303
  const char *p;
304
 
305
  p = strrchr (lbasename (s), '.');
306
  if (! p)
307
    p = s + strlen (s);
308
 
309
  obstack_grow (&temporary_obstack, s, p - s);
310
  return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext));
311
}
312
 
313
static char *
314
obstack_fgets (FILE *stream, struct obstack *ob)
315
{
316
  int c;
317
  while ((c = getc (stream)) != EOF && c != '\n')
318
    obstack_1grow (ob, c);
319
  if (obstack_object_size (ob) == 0)
320
    return NULL;
321
  obstack_1grow (ob, '\0');
322
  return XOBFINISH (ob, char *);
323
}
324
 
325
static char *
326
tfgets (FILE *stream)
327
{
328
  return obstack_fgets (stream, &temporary_obstack);
329
}
330
 
331
static char *
332
pfgets (FILE *stream)
333
{
334
  return xstrdup (tfgets (stream));
335
}
336
 
337
/* Real tlink code.  */
338
 
339
/* Subroutine of read_repo_file.  We are reading the repo file for file F,
340
   which is coming in on STREAM, and the symbol that comes next in STREAM
341
   is offered, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
342
 
343
   XXX "provided" is unimplemented, both here and in the compiler.  */
344
 
345
static void
346
freadsym (FILE *stream, file *f, int chosen)
347
{
348
  symbol *sym;
349
 
350
  {
351
    const char *name = tfgets (stream);
352
    sym = symbol_hash_lookup (name, true);
353
  }
354
 
355
  if (sym->file == NULL)
356
    {
357
      /* We didn't have this symbol already, so we choose this file.  */
358
 
359
      symbol_push (sym);
360
      sym->file = f;
361
      sym->chosen = chosen;
362
    }
363
  else if (chosen)
364
    {
365
      /* We want this file; cast aside any pretender.  */
366
 
367
      if (sym->chosen && sym->file != f)
368
        {
369
          if (sym->chosen == 1)
370
            file_push (sym->file);
371
          else
372
            {
373
              file_push (f);
374
              f = sym->file;
375
              chosen = sym->chosen;
376
            }
377
        }
378
      sym->file = f;
379
      sym->chosen = chosen;
380
    }
381
}
382
 
383
/* Read in the repo file denoted by F, and record all its information.  */
384
 
385
static void
386
read_repo_file (file *f)
387
{
388
  char c;
389
  FILE *stream = fopen (f->key, "r");
390
 
391
  if (tlink_verbose >= 2)
392
    fprintf (stderr, _("collect: reading %s\n"), f->key);
393
 
394
  while (fscanf (stream, "%c ", &c) == 1)
395
    {
396
      switch (c)
397
        {
398
        case 'A':
399
          f->args = pfgets (stream);
400
          break;
401
        case 'D':
402
          f->dir = pfgets (stream);
403
          break;
404
        case 'M':
405
          f->main = pfgets (stream);
406
          break;
407
        case 'P':
408
          freadsym (stream, f, 2);
409
          break;
410
        case 'C':
411
          freadsym (stream, f, 1);
412
          break;
413
        case 'O':
414
          freadsym (stream, f, 0);
415
          break;
416
        }
417
      obstack_free (&temporary_obstack, temporary_firstobj);
418
    }
419
  fclose (stream);
420
  if (f->args == NULL)
421
    f->args = getenv ("COLLECT_GCC_OPTIONS");
422
  if (f->dir == NULL)
423
    f->dir = ".";
424
}
425
 
426
/* We might want to modify LINE, which is a symbol line from file F.  We do
427
   this if either we saw an error message referring to the symbol in
428
   question, or we have already allocated the symbol to another file and
429
   this one wants to emit it as well.  */
430
 
431
static void
432
maybe_tweak (char *line, file *f)
433
{
434
  symbol *sym = symbol_hash_lookup (line + 2, false);
435
 
436
  if ((sym->file == f && sym->tweaking)
437
      || (sym->file != f && line[0] == 'C'))
438
    {
439
      sym->tweaking = 0;
440
      sym->tweaked = 1;
441
 
442
      if (line[0] == 'O')
443
        {
444
          line[0] = 'C';
445
          sym->chosen = 1;
446
        }
447
      else
448
        {
449
          line[0] = 'O';
450
          sym->chosen = 0;
451
        }
452
    }
453
}
454
 
455
/* Update the repo files for each of the object files we have adjusted and
456
   recompile.  */
457
 
458
static int
459
recompile_files (void)
460
{
461
  file *f;
462
 
463
  putenv (xstrdup ("COMPILER_PATH="));
464
  putenv (xstrdup ("LIBRARY_PATH="));
465
 
466
  while ((f = file_pop ()) != NULL)
467
    {
468
      char *line;
469
      const char *p, *q;
470
      char **argv;
471
      struct obstack arg_stack;
472
      FILE *stream = fopen (f->key, "r");
473
      const char *const outname = frob_extension (f->key, ".rnw");
474
      FILE *output = fopen (outname, "w");
475
 
476
      while ((line = tfgets (stream)) != NULL)
477
        {
478
          switch (line[0])
479
            {
480
            case 'C':
481
            case 'O':
482
              maybe_tweak (line, f);
483
            }
484
          fprintf (output, "%s\n", line);
485
        }
486
      fclose (stream);
487
      fclose (output);
488
      /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if
489
         the new file name already exists.  Therefore, we explicitly
490
         remove the old file first.  */
491
      if (remove (f->key) == -1)
492
        fatal_error ("removing .rpo file: %m");
493
      if (rename (outname, f->key) == -1)
494
        fatal_error ("renaming .rpo file: %m");
495
 
496
      if (!f->args)
497
        {
498
          error ("repository file '%s' does not contain command-line "
499
                 "arguments", f->key);
500
          return 0;
501
        }
502
 
503
      /* Build a null-terminated argv array suitable for
504
         tlink_execute().  Manipulate arguments on the arg_stack while
505
         building argv on the temporary_obstack.  */
506
 
507
      obstack_init (&arg_stack);
508
      obstack_ptr_grow (&temporary_obstack, c_file_name);
509
 
510
      for (p = f->args; *p != '\0'; p = q + 1)
511
        {
512
          /* Arguments are delimited by single-quotes.  Find the
513
             opening quote.  */
514
          p = strchr (p, '\'');
515
          if (!p)
516
            goto done;
517
 
518
          /* Find the closing quote.  */
519
          q = strchr (p + 1, '\'');
520
          if (!q)
521
            goto done;
522
 
523
          obstack_grow (&arg_stack, p + 1, q - (p + 1));
524
 
525
          /* Replace '\'' with '.  This is how set_collect_gcc_options
526
             encodes a single-quote.  */
527
          while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'')
528
            {
529
              const char *r;
530
 
531
              r = strchr (q + 4, '\'');
532
              if (!r)
533
                goto done;
534
 
535
              obstack_grow (&arg_stack, q + 3, r - (q + 3));
536
              q = r;
537
            }
538
 
539
          obstack_1grow (&arg_stack, '\0');
540
          obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack));
541
        }
542
    done:
543
      obstack_ptr_grow (&temporary_obstack, f->main);
544
      obstack_ptr_grow (&temporary_obstack, NULL);
545
      argv = XOBFINISH (&temporary_obstack, char **);
546
 
547
      if (tlink_verbose)
548
        fprintf (stderr, _("collect: recompiling %s\n"), f->main);
549
 
550
      if (chdir (f->dir) != 0
551
          || tlink_execute (c_file_name, argv, NULL, NULL) != 0
552
          || chdir (initial_cwd) != 0)
553
        return 0;
554
 
555
      read_repo_file (f);
556
 
557
      obstack_free (&arg_stack, NULL);
558
      obstack_free (&temporary_obstack, temporary_firstobj);
559
    }
560
  return 1;
561
}
562
 
563
/* The first phase of processing: determine which object files have
564
   .rpo files associated with them, and read in the information.  */
565
 
566
static int
567
read_repo_files (char **object_lst)
568
{
569
  char **object = object_lst;
570
 
571
  for (; *object; object++)
572
    {
573
      const char *p;
574
      file *f;
575
 
576
      /* Don't bother trying for ld flags.  */
577
      if (*object[0] == '-')
578
        continue;
579
 
580
      p = frob_extension (*object, ".rpo");
581
 
582
      if (! file_exists (p))
583
        continue;
584
 
585
      f = file_hash_lookup (p);
586
 
587
      read_repo_file (f);
588
    }
589
 
590
  if (file_stack != NULL && ! recompile_files ())
591
    return 0;
592
 
593
  return (symbol_stack != NULL);
594
}
595
 
596
/* Add the demangled forms of any new symbols to the hash table.  */
597
 
598
static void
599
demangle_new_symbols (void)
600
{
601
  symbol *sym;
602
 
603
  while ((sym = symbol_pop ()) != NULL)
604
    {
605
      demangled *dem;
606
      const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI);
607
 
608
      if (! p)
609
        continue;
610
 
611
      dem = demangled_hash_lookup (p, true);
612
      VEC_safe_push (str, heap, dem->mangled, sym->key);
613
    }
614
}
615
 
616
/* We want to tweak symbol SYM.  Return true if all is well, false on
617
   error.  */
618
 
619
static bool
620
start_tweaking (symbol *sym)
621
{
622
  if (sym && sym->tweaked)
623
    {
624
      error ("'%s' was assigned to '%s', but was not defined "
625
             "during recompilation, or vice versa",
626
             sym->key, sym->file->key);
627
      return 0;
628
    }
629
  if (sym && !sym->tweaking)
630
    {
631
      if (tlink_verbose >= 2)
632
        fprintf (stderr, _("collect: tweaking %s in %s\n"),
633
                 sym->key, sym->file->key);
634
      sym->tweaking = 1;
635
      file_push (sym->file);
636
    }
637
  return true;
638
}
639
 
640
/* Step through the output of the linker, in the file named FNAME, and
641
   adjust the settings for each symbol encountered.  */
642
 
643
static int
644
scan_linker_output (const char *fname)
645
{
646
  FILE *stream = fopen (fname, "r");
647
  char *line;
648
  int skip_next_in_line = 0;
649
 
650
  while ((line = tfgets (stream)) != NULL)
651
    {
652
      char *p = line, *q;
653
      symbol *sym;
654
      demangled *dem = 0;
655
      int end;
656
      int ok = 0;
657
      unsigned ix;
658
      str s;
659
 
660
      /* On darwin9, we might have to skip " in " lines as well.  */
661
      if (skip_next_in_line
662
          && strstr (p, " in "))
663
          continue;
664
      skip_next_in_line = 0;
665
 
666
      while (*p && ISSPACE ((unsigned char) *p))
667
        ++p;
668
 
669
      if (! *p)
670
        continue;
671
 
672
      for (q = p; *q && ! ISSPACE ((unsigned char) *q); ++q)
673
        ;
674
 
675
      /* Try the first word on the line.  */
676
      if (*p == '.')
677
        ++p;
678
      if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
679
        p += strlen (USER_LABEL_PREFIX);
680
 
681
      end = ! *q;
682
      *q = 0;
683
      sym = symbol_hash_lookup (p, false);
684
 
685
      /* Some SVR4 linkers produce messages like
686
         ld: 0711-317 ERROR: Undefined symbol: .g__t3foo1Zi
687
         */
688
      if (! sym && ! end && strstr (q + 1, "Undefined symbol: "))
689
        {
690
          char *p = strrchr (q + 1, ' ');
691
          p++;
692
          if (*p == '.')
693
            p++;
694
          if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
695
            p += strlen (USER_LABEL_PREFIX);
696
          sym = symbol_hash_lookup (p, false);
697
        }
698
 
699
      if (! sym && ! end)
700
        /* Try a mangled name in quotes.  */
701
        {
702
          char *oldq = q + 1;
703
          q = 0;
704
 
705
          /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)*  */
706
          if (strcmp (oldq, "referenced from:") == 0)
707
            {
708
              /* We have to remember that we found a symbol to tweak.  */
709
              ok = 1;
710
 
711
              /* We actually want to start from the first word on the
712
                 line.  */
713
              oldq = p;
714
 
715
              /* Since the format is multiline, we have to skip
716
                 following lines with " in ".  */
717
              skip_next_in_line = 1;
718
            }
719
 
720
          /* First try `GNU style'.  */
721
          p = strchr (oldq, '`');
722
          if (p)
723
            p++, q = strchr (p, '\'');
724
          /* Then try "double quotes".  */
725
          else if (p = strchr (oldq, '"'), p)
726
            p++, q = strchr (p, '"');
727
          /* Then try 'single quotes'.  */
728
          else if (p = strchr (oldq, '\''), p)
729
            p++, q = strchr (p, '\'');
730
          else {
731
            /* Then try entire line.  */
732
            q = strchr (oldq, 0);
733
            if (q != oldq)
734
              p = (char *)oldq;
735
          }
736
 
737
          if (p)
738
            {
739
              /* Don't let the strstr's below see the demangled name; we
740
                 might get spurious matches.  */
741
              p[-1] = '\0';
742
 
743
              /* powerpc64-linux references .foo when calling function foo.  */
744
              if (*p == '.')
745
                p++;
746
            }
747
 
748
          /* We need to check for certain error keywords here, or we would
749
             mistakenly use GNU ld's "In function `foo':" message.  */
750
          if (q && (ok
751
                    || strstr (oldq, "ndefined")
752
                    || strstr (oldq, "nresolved")
753
                    || strstr (oldq, "nsatisfied")
754
                    || strstr (oldq, "ultiple")))
755
            {
756
              *q = 0;
757
              dem = demangled_hash_lookup (p, false);
758
              if (!dem)
759
                {
760
                  if (!strncmp (p, USER_LABEL_PREFIX,
761
                                strlen (USER_LABEL_PREFIX)))
762
                    p += strlen (USER_LABEL_PREFIX);
763
                  sym = symbol_hash_lookup (p, false);
764
                }
765
            }
766
        }
767
 
768
      if (dem)
769
        {
770
          /* We found a demangled name.  If this is the name of a
771
             constructor or destructor, there can be several mangled names
772
             that match it, so choose or unchoose all of them.  If some are
773
             chosen and some not, leave the later ones that don't match
774
             alone for now; either this will cause the link to suceed, or
775
             on the next attempt we will switch all of them the other way
776
             and that will cause it to succeed.  */
777
          int chosen = 0;
778
          int len = VEC_length (str, dem->mangled);
779
          ok = true;
780
          FOR_EACH_VEC_ELT (str, dem->mangled, ix, s)
781
            {
782
              sym = symbol_hash_lookup (s, false);
783
              if (ix == 0)
784
                chosen = sym->chosen;
785
              else if (sym->chosen != chosen)
786
                /* Mismatch.  */
787
                continue;
788
              /* Avoid an error about re-tweaking when we guess wrong in
789
                 the case of mismatch.  */
790
              if (len > 1)
791
                sym->tweaked = false;
792
              ok = start_tweaking (sym);
793
            }
794
        }
795
      else
796
        ok = start_tweaking (sym);
797
 
798
      obstack_free (&temporary_obstack, temporary_firstobj);
799
 
800
      if (!ok)
801
        {
802
          fclose (stream);
803
          return 0;
804
        }
805
    }
806
 
807
  fclose (stream);
808
  return (file_stack != NULL);
809
}
810
 
811
/* Entry point for tlink.  Called from main in collect2.c.
812
 
813
   Iteratively try to provide definitions for all the unresolved symbols
814
   mentioned in the linker error messages.
815
 
816
   LD_ARGV is an array of arguments for the linker.
817
   OBJECT_LST is an array of object files that we may be able to recompile
818
     to provide missing definitions.  Currently ignored.  */
819
 
820
void
821
do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
822
{
823
  int exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
824
 
825
  tlink_init ();
826
 
827
  if (exit)
828
    {
829
      int i = 0;
830
 
831
      /* Until collect does a better job of figuring out which are object
832
         files, assume that everything on the command line could be.  */
833
      if (read_repo_files (ld_argv))
834
        while (exit && i++ < MAX_ITERATIONS)
835
          {
836
            if (tlink_verbose >= 3)
837
              {
838
                dump_file (ldout, stdout);
839
                dump_file (lderrout, stderr);
840
              }
841
            demangle_new_symbols ();
842
            if (! scan_linker_output (ldout)
843
                && ! scan_linker_output (lderrout))
844
              break;
845
            if (! recompile_files ())
846
              break;
847
            if (tlink_verbose)
848
              fprintf (stderr, _("collect: relinking\n"));
849
            exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
850
          }
851
    }
852
 
853
  dump_file (ldout, stdout);
854
  unlink (ldout);
855
  dump_file (lderrout, stderr);
856
  unlink (lderrout);
857
  if (exit)
858
    {
859
      error ("ld returned %d exit status", exit);
860
      collect_exit (exit);
861
    }
862
}

powered by: WebSVN 2.1.0

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