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