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