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