]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tlink.c
Makefile.in (tlink.o): Don't depend on toplev.h.
[thirdparty/gcc.git] / gcc / tlink.c
CommitLineData
aa32d841
JL
1/* Scan linker error messages for missing template instantiations and provide
2 them.
3
2e6a5989 4 Copyright (C) 1995, 1998 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 {
d4058195 553 const char *p = frob_extension (*object, ".rpo");
aa32d841
JL
554 file *f;
555
556 if (! file_exists (p))
557 continue;
558
559 f = file_hash_lookup (p);
560
561 read_repo_file (f);
562 }
563
564 if (file_stack != NULL && ! recompile_files ())
565 return 0;
566
567 return (symbol_stack != NULL);
568}
569
eb686064
JM
570/* Add the demangled forms of any new symbols to the hash table. */
571
aa32d841
JL
572static void
573demangle_new_symbols ()
574{
575 symbol *sym;
576
577 while ((sym = symbol_pop ()) != NULL)
578 {
579 demangled *dem;
d4058195 580 const char *p = cplus_demangle ((char*) sym->root.key,
a87ec9e6 581 DMGL_PARAMS | DMGL_ANSI);
aa32d841
JL
582
583 if (! p)
584 continue;
585
586 dem = demangled_hash_lookup (p, true);
a87ec9e6 587 dem->mangled = (char*) sym->root.key;
aa32d841
JL
588 }
589}
590
eb686064
JM
591/* Step through the output of the linker, in the file named FNAME, and
592 adjust the settings for each symbol encountered. */
593
aa32d841
JL
594static int
595scan_linker_output (fname)
54ea1de9 596 const char *fname;
aa32d841
JL
597{
598 FILE *stream = fopen (fname, "r");
599 char *line;
600
601 while ((line = tfgets (stream)) != NULL)
602 {
603 char *p = line, *q;
604 symbol *sym;
605 int end;
606
79c9824e 607 while (*p && ISSPACE ((unsigned char)*p))
aa32d841
JL
608 ++p;
609
610 if (! *p)
611 continue;
612
79c9824e 613 for (q = p; *q && ! ISSPACE ((unsigned char)*q); ++q)
aa32d841
JL
614 ;
615
616 /* Try the first word on the line. */
617 if (*p == '.')
618 ++p;
619 if (*p == '_' && prepends_underscore)
620 ++p;
621
622 end = ! *q;
623 *q = 0;
624 sym = symbol_hash_lookup (p, false);
625
626 if (! sym && ! end)
b4558b57 627 /* Try a mangled name in quotes. */
aa32d841 628 {
d4058195 629 const char *oldq = q+1;
aa32d841 630 demangled *dem = 0;
aa32d841
JL
631 q = 0;
632
b4558b57
JM
633 /* First try `GNU style'. */
634 p = index (oldq, '`');
635 if (p)
636 p++, q = index (p, '\'');
637 /* Then try "double quotes". */
638 else if (p = index (oldq, '"'), p)
639 p++, q = index (p, '"');
aa32d841 640
b4558b57 641 if (q)
aa32d841 642 {
b4558b57
JM
643 *q = 0;
644 dem = demangled_hash_lookup (p, false);
645 if (dem)
646 sym = symbol_hash_lookup (dem->mangled, false);
647 else
9c5b50b3
JM
648 {
649 if (*p == '_' && prepends_underscore)
650 ++p;
651 sym = symbol_hash_lookup (p, false);
652 }
aa32d841 653 }
aa32d841
JL
654 }
655
656 if (sym && sym->tweaked)
7b6ffd11
KI
657 {
658 fclose (stream);
659 return 0;
660 }
aa32d841
JL
661 if (sym && !sym->tweaking)
662 {
663 if (tlink_verbose >= 2)
664 fprintf (stderr, "collect: tweaking %s in %s\n",
a87ec9e6 665 (char*) sym->root.key, (char*) sym->file->root.key);
aa32d841
JL
666 sym->tweaking = 1;
667 file_push (sym->file);
668 }
669
670 obstack_free (&temporary_obstack, temporary_firstobj);
671 }
672
7b6ffd11 673 fclose (stream);
aa32d841
JL
674 return (file_stack != NULL);
675}
676
eb686064
JM
677/* Entry point for tlink. Called from main in collect2.c.
678
679 Iteratively try to provide definitions for all the unresolved symbols
680 mentioned in the linker error messages.
681
682 LD_ARGV is an array of arguments for the linker.
683 OBJECT_LST is an array of object files that we may be able to recompile
684 to provide missing definitions. Currently ignored. */
685
aa32d841
JL
686void
687do_tlink (ld_argv, object_lst)
d4058195 688 char **ld_argv, **object_lst ATTRIBUTE_UNUSED;
aa32d841
JL
689{
690 int exit = tlink_execute ("ld", ld_argv, ldout);
691
692 tlink_init ();
693
694 if (exit)
695 {
696 int i = 0;
697
698 /* Until collect does a better job of figuring out which are object
699 files, assume that everything on the command line could be. */
700 if (read_repo_files (ld_argv))
701 while (exit && i++ < MAX_ITERATIONS)
702 {
703 if (tlink_verbose >= 3)
704 dump_file (ldout);
705 demangle_new_symbols ();
706 if (! scan_linker_output (ldout))
707 break;
708 if (! recompile_files ())
709 break;
710 if (tlink_verbose)
711 fprintf (stderr, "collect: relinking\n");
712 exit = tlink_execute ("ld", ld_argv, ldout);
713 }
714 }
715
716 dump_file (ldout);
717 unlink (ldout);
718 if (exit)
719 {
720 error ("ld returned %d exit status", exit);
721 collect_exit (exit);
722 }
723}