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