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