tlink.c revision 260011
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 = XCNEW (struct symbol_hash_entry);
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 = XCNEW (struct file_hash_entry);
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 = XCNEW (struct demangled_hash_entry);
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, "%s", _("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  int skip_next_in_line = 0;
611
612  while ((line = tfgets (stream)) != NULL)
613    {
614      char *p = line, *q;
615      symbol *sym;
616      int end;
617      int ok = 0;
618
619      /* On darwin9, we might have to skip " in " lines as well.  */
620      if (skip_next_in_line
621	  && strstr (p, " in "))
622	  continue;
623      skip_next_in_line = 0;
624
625      while (*p && ISSPACE ((unsigned char) *p))
626	++p;
627
628      if (! *p)
629	continue;
630
631      for (q = p; *q && ! ISSPACE ((unsigned char) *q); ++q)
632	;
633
634      /* Try the first word on the line.  */
635      if (*p == '.')
636	++p;
637      if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
638	p += strlen (USER_LABEL_PREFIX);
639
640      end = ! *q;
641      *q = 0;
642      sym = symbol_hash_lookup (p, false);
643
644      /* Some SVR4 linkers produce messages like
645	 ld: 0711-317 ERROR: Undefined symbol: .g__t3foo1Zi
646	 */
647      if (! sym && ! end && strstr (q + 1, "Undefined symbol: "))
648	{
649	  char *p = strrchr (q + 1, ' ');
650	  p++;
651	  if (*p == '.')
652	    p++;
653	  if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
654	    p += strlen (USER_LABEL_PREFIX);
655	  sym = symbol_hash_lookup (p, false);
656	}
657
658      if (! sym && ! end)
659	/* Try a mangled name in quotes.  */
660	{
661	  const char *oldq = q + 1;
662	  demangled *dem = 0;
663	  q = 0;
664
665	  /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)*  */
666	  if (strcmp (oldq, "referenced from:") == 0)
667	    {
668	      /* We have to remember that we found a symbol to tweak.  */
669	      ok = 1;
670
671	      /* We actually want to start from the first word on the
672		 line.  */
673	      oldq = p;
674
675	      /* Since the format is multiline, we have to skip
676		 following lines with " in ".  */
677	      skip_next_in_line = 1;
678	    }
679
680	  /* First try `GNU style'.  */
681	  p = strchr (oldq, '`');
682	  if (p)
683	    p++, q = strchr (p, '\'');
684	  /* Then try "double quotes".  */
685	  else if (p = strchr (oldq, '"'), p)
686	    p++, q = strchr (p, '"');
687	  else {
688	    /* Then try entire line.  */
689	    q = strchr (oldq, 0);
690	    if (q != oldq)
691	      p = (char *)oldq;
692	  }
693
694	  if (p)
695	    {
696	      /* Don't let the strstr's below see the demangled name; we
697		 might get spurious matches.  */
698	      p[-1] = '\0';
699
700	      /* powerpc64-linux references .foo when calling function foo.  */
701	      if (*p == '.')
702		p++;
703	    }
704
705	  /* We need to check for certain error keywords here, or we would
706	     mistakenly use GNU ld's "In function `foo':" message.  */
707	  if (q && (ok
708		    || strstr (oldq, "ndefined")
709		    || strstr (oldq, "nresolved")
710		    || strstr (oldq, "nsatisfied")
711		    || strstr (oldq, "ultiple")))
712	    {
713	      *q = 0;
714	      dem = demangled_hash_lookup (p, false);
715	      if (dem)
716		sym = symbol_hash_lookup (dem->mangled, false);
717	      else
718		{
719		  if (!strncmp (p, USER_LABEL_PREFIX,
720				strlen (USER_LABEL_PREFIX)))
721		    p += strlen (USER_LABEL_PREFIX);
722		  sym = symbol_hash_lookup (p, false);
723		}
724	    }
725	}
726
727      if (sym && sym->tweaked)
728	{
729	  error ("'%s' was assigned to '%s', but was not defined "
730		 "during recompilation, or vice versa",
731		 sym->key, sym->file->key);
732	  fclose (stream);
733	  return 0;
734	}
735      if (sym && !sym->tweaking)
736	{
737	  if (tlink_verbose >= 2)
738	    fprintf (stderr, _("collect: tweaking %s in %s\n"),
739		     sym->key, sym->file->key);
740	  sym->tweaking = 1;
741	  file_push (sym->file);
742	}
743
744      obstack_free (&temporary_obstack, temporary_firstobj);
745    }
746
747  fclose (stream);
748  return (file_stack != NULL);
749}
750
751/* Entry point for tlink.  Called from main in collect2.c.
752
753   Iteratively try to provide definitions for all the unresolved symbols
754   mentioned in the linker error messages.
755
756   LD_ARGV is an array of arguments for the linker.
757   OBJECT_LST is an array of object files that we may be able to recompile
758     to provide missing definitions.  Currently ignored.  */
759
760void
761do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
762{
763  int exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
764
765  tlink_init ();
766
767  if (exit)
768    {
769      int i = 0;
770
771      /* Until collect does a better job of figuring out which are object
772	 files, assume that everything on the command line could be.  */
773      if (read_repo_files (ld_argv))
774	while (exit && i++ < MAX_ITERATIONS)
775	  {
776	    if (tlink_verbose >= 3)
777	      {
778		dump_file (ldout, stdout);
779		dump_file (lderrout, stderr);
780	      }
781	    demangle_new_symbols ();
782	    if (! scan_linker_output (ldout)
783		&& ! scan_linker_output (lderrout))
784	      break;
785	    if (! recompile_files ())
786	      break;
787	    if (tlink_verbose)
788	      fprintf (stderr, _("collect: relinking\n"));
789	    exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
790	  }
791    }
792
793  dump_file (ldout, stdout);
794  unlink (ldout);
795  dump_file (lderrout, stderr);
796  unlink (lderrout);
797  if (exit)
798    {
799      error ("ld returned %d exit status", exit);
800      collect_exit (exit);
801    }
802}
803