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