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