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