xref: /dragonfly/contrib/gcc-4.7/gcc/tlink.c (revision 0ca59c34)
1 /* 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, 2013 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 ret = tlink_execute ("ld", ld_argv, ldout, lderrout);
824 
825   tlink_init ();
826 
827   if (ret)
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 (ret && 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 	    ret = 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 (ret)
858     {
859       error ("ld returned %d exit status", ret);
860       exit (ret);
861     }
862 }
863