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