Commit | Line | Data |
---|---|---|
2fa0b342 DHW |
1 | /* Copyright (C) 1991 Free Software Foundation, Inc. |
2 | ||
3 | This file is part of GLD, the Gnu Linker. | |
4 | ||
5 | GLD is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 1, or (at your option) | |
8 | any later version. | |
9 | ||
10 | GLD is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with GLD; see the file COPYING. If not, write to | |
17 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
18 | ||
19 | /* | |
20 | * Written by Steve Chamberlain steve@cygnus.com | |
21 | * | |
22 | * $Id$ | |
23 | * | |
24 | * $Log$ | |
25 | * Revision 1.1 1991/03/21 21:28:52 gumby | |
26 | * Initial revision | |
27 | * | |
28 | * Revision 1.1 1991/03/13 00:48:27 chrisb | |
29 | * Initial revision | |
30 | * | |
31 | * Revision 1.7 1991/03/10 19:15:45 sac | |
32 | * Fixed a prototype problem | |
33 | * | |
34 | * Revision 1.6 1991/03/10 09:31:32 rich | |
35 | * Modified Files: | |
36 | * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c | |
37 | * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h | |
38 | * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c | |
39 | * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c | |
40 | * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h | |
41 | * | |
42 | * As of this round of changes, ld now builds on all hosts of (Intel960) | |
43 | * interest and copy passes my copy test on big endian hosts again. | |
44 | * | |
45 | * Revision 1.5 1991/03/09 03:31:02 sac | |
46 | * After a fatal info message, the output file is deleted. | |
47 | * | |
48 | * Revision 1.4 1991/03/06 02:28:31 sac | |
49 | * Fixed partial linking and error messages. | |
50 | * | |
51 | * Revision 1.3 1991/02/22 17:15:02 sac | |
52 | * Added RCS keywords and copyrights | |
53 | * | |
54 | * | |
55 | */ | |
56 | ||
57 | ||
58 | #include "sysdep.h" | |
59 | #include "bfd.h" | |
60 | ||
61 | #include "config.h" | |
62 | #include "ld.h" | |
63 | #include "ldmain.h" | |
64 | #include "ldmisc.h" | |
65 | #include "ldwrite.h" | |
66 | #include "ldgram.h" | |
67 | #include "ldsym.h" | |
68 | #include "ldlang.h" | |
69 | #include "ld-emul.h" | |
70 | #include "ldlex.h" | |
71 | #include "ldfile.h" | |
72 | ||
73 | /* IMPORTS */ | |
74 | extern boolean lang_has_input_file; | |
75 | ||
76 | /* EXPORTS */ | |
77 | ||
78 | char *default_target; | |
79 | char *output_filename = "a.out"; | |
80 | /* Name this program was invoked by. */ | |
81 | char *program_name; | |
82 | ||
83 | /* The file that we're creating */ | |
84 | bfd *output_bfd; | |
85 | ||
86 | extern boolean option_v; | |
87 | ||
88 | /* The local symbol prefix */ | |
89 | char lprefix = 'L'; | |
90 | ||
91 | /* Count the number of global symbols multiply defined. */ | |
92 | int multiple_def_count; | |
93 | ||
94 | ||
95 | /* Count the number of symbols defined through common declarations. | |
96 | This count is referenced in symdef_library, linear_library, and | |
97 | modified by enter_global_ref. | |
98 | ||
99 | It is incremented when a symbol is created as a common, and | |
100 | decremented when the common declaration is overridden | |
101 | ||
102 | Another way of thinking of it is that this is a count of | |
103 | all ldsym_types with a ->scoms field | |
104 | */ | |
105 | unsigned int commons_pending; | |
106 | ||
107 | ||
108 | /* Count the number of global symbols referenced and not defined. | |
109 | common symbols are not included in this count. | |
110 | */ | |
111 | ||
112 | unsigned int undefined_global_sym_count; | |
113 | ||
114 | ||
115 | ||
116 | /* Count the number of warning symbols encountered. */ | |
117 | int warning_count; | |
118 | ||
119 | /* have we had a load script ? */ | |
120 | extern boolean had_script; | |
121 | ||
122 | ||
123 | ||
124 | /* Nonzero means print names of input files as processed. */ | |
125 | boolean trace_files; | |
126 | ||
127 | ||
128 | ||
129 | /* 1 => write load map. */ | |
130 | boolean write_map; | |
131 | ||
132 | ||
133 | int unix_relocate; | |
134 | ||
135 | ||
136 | ||
137 | ||
138 | ||
139 | ||
140 | ||
141 | ||
142 | /* Force the make_executable to be output, even if there are non-fatal | |
143 | errors */ | |
144 | boolean force_make_executable; | |
145 | ||
146 | ||
147 | /* A count of the total number of local symbols ever seen - by adding | |
148 | the symbol_count field of each newly read afile.*/ | |
149 | ||
150 | ||
151 | unsigned int total_symbols_seen; | |
152 | ||
153 | /* A count of the number of read files - the same as the number of elements | |
154 | in file_chain | |
155 | */ | |
156 | unsigned int total_files_seen; | |
157 | ||
158 | ||
159 | /* IMPORTS */ | |
160 | args_type command_line; | |
161 | ld_config_type config; | |
162 | int | |
163 | main (argc, argv) | |
164 | char **argv; | |
165 | int argc; | |
166 | { | |
167 | char *emulation; | |
168 | program_name = argv[0]; | |
169 | output_filename = "a.out"; | |
170 | ||
171 | emulation = getenv(EMULATION_ENVIRON); | |
172 | ||
173 | /* Initialize the data about options. */ | |
174 | strip_symbols = STRIP_NONE; | |
175 | trace_files = false; | |
176 | discard_locals = DISCARD_NONE; | |
177 | ||
178 | write_map = false; | |
179 | config.relocateable_output = false; | |
180 | unix_relocate = 0; | |
181 | command_line.force_common_definition = false; | |
182 | ||
183 | ldfile_add_arch(""); | |
184 | ||
185 | config.make_executable = true; | |
186 | force_make_executable = false; | |
187 | ||
188 | ||
189 | /* Initialize the cumulative counts of symbols. */ | |
190 | undefined_global_sym_count = 0; | |
191 | warning_count = 0; | |
192 | multiple_def_count = 0; | |
193 | commons_pending = 0; | |
194 | ||
195 | config.magic_demand_paged = true ; | |
196 | config.make_executable = true; | |
197 | ||
198 | if (emulation == (char *)NULL) { | |
199 | emulation= DEFAULT_EMULATION; | |
200 | } | |
201 | ldemul_choose_mode(emulation); | |
202 | ||
203 | default_target = ldemul_choose_target(); | |
204 | ||
205 | lang_init(); | |
206 | ldemul_before_parse(); | |
207 | ||
208 | lang_has_input_file = false; | |
209 | parse_args(argc, argv); | |
210 | ||
211 | if (lang_has_input_file == false) { | |
212 | info("%P%F: No input files\n"); | |
213 | } | |
214 | ||
215 | ldemul_after_parse(); | |
216 | ||
217 | lang_process(); | |
218 | ||
219 | ||
220 | ||
221 | ||
222 | /* Print error messages for any missing symbols, for any warning | |
223 | symbols, and possibly multiple definitions */ | |
224 | ||
225 | /* Print a map, if requested. */ | |
226 | ||
227 | if (write_map) { | |
228 | ldsym_print_symbol_table (); | |
229 | lang_map(stdout); | |
230 | } | |
231 | ||
232 | ||
233 | if (config.relocateable_output) { | |
234 | output_bfd->flags &= ~( D_PAGED); | |
235 | output_bfd->flags |= EXEC_P; | |
236 | ldwrite(); | |
237 | bfd_close(output_bfd); | |
238 | } | |
239 | else { | |
240 | output_bfd->flags |= EXEC_P; | |
241 | ||
242 | ldwrite(); | |
243 | bfd_close(output_bfd); | |
244 | if (config.make_executable == false && force_make_executable == false) { | |
245 | unlink(output_filename); | |
246 | } | |
247 | return (!config.make_executable); | |
248 | } | |
249 | ||
250 | return(0); | |
251 | } /* main() */ | |
252 | ||
253 | ||
254 | void | |
255 | Q_read_entry_symbols (desc, entry) | |
256 | bfd *desc; | |
257 | struct lang_input_statement_struct *entry; | |
258 | { | |
259 | if (entry->asymbols == (asymbol **)NULL) { | |
260 | size_t table_size = get_symtab_upper_bound(desc); | |
261 | entry->asymbols = (asymbol **)ldmalloc(table_size); | |
262 | ||
263 | entry->symbol_count = bfd_canonicalize_symtab(desc, entry->asymbols) ; | |
264 | } | |
265 | } | |
266 | ||
267 | ||
268 | /* | |
269 | * turn this item into a reference | |
270 | */ | |
271 | static void | |
272 | refize(sp, nlist_p) | |
273 | ldsym_type *sp; | |
274 | asymbol **nlist_p; | |
275 | { | |
276 | asymbol *sym = *nlist_p; | |
277 | sym->value = 0; | |
278 | sym->flags = BSF_UNDEFINED; | |
279 | sym->section = (asection *)NULL; | |
280 | sym->udata =(void *)( sp->srefs_chain); | |
281 | sp->srefs_chain = nlist_p; | |
282 | } | |
283 | /* | |
284 | This function is called for each name which is seen which has a global | |
285 | scope. It enters the name into the global symbol table in the correct | |
286 | symbol on the correct chain. Remember that each ldsym_type has three | |
287 | chains attatched, one of all definitions of a symbol, one of all | |
288 | references of a symbol and one of all common definitions of a symbol. | |
289 | ||
290 | When the function is over, the supplied is left connected to the bfd | |
291 | to which is was born, with its udata field pointing to the next member | |
292 | on the chain in which it has been inserted. | |
293 | ||
294 | A certain amount of jigery pokery is necessary since commons come | |
295 | along and upset things, we only keep one item in the common chain; the | |
296 | one with the biggest size seen sofar. When another common comes along | |
297 | it either bumps the previous definition into the ref chain, since it | |
298 | is bigger, or gets turned into a ref on the spot since the one on the | |
299 | common chain is already bigger. If a real definition comes along then | |
300 | the common gets bumped off anyway. | |
301 | ||
302 | Whilst all this is going on we keep a count of the number of multiple | |
303 | definitions seen, undefined global symbols and pending commons. | |
304 | */ | |
305 | ||
306 | ||
307 | void | |
308 | Q_enter_global_ref (nlist_p) | |
309 | asymbol **nlist_p; | |
310 | ||
311 | { | |
312 | asymbol *sym = *nlist_p; | |
313 | char *name = sym->name; | |
314 | ldsym_type *sp = ldsym_get (name); | |
315 | ||
316 | flagword this_symbol_flags = sym->flags; | |
317 | ||
318 | ||
319 | ASSERT(sym->udata == 0); | |
320 | ||
321 | /* Just place onto correct chain */ | |
322 | if (flag_is_common(this_symbol_flags)) { | |
323 | /* If we have a definition of this symbol already then | |
324 | * this common turns into a reference. Also we only | |
325 | * ever point to the largest common, so if we | |
326 | * have a common, but it's bigger that the new symbol | |
327 | * the turn this into a reference too. | |
328 | */ | |
329 | if (sp->sdefs_chain) | |
330 | { | |
331 | /* This is a common symbol, but we already have a definition | |
332 | for it, so just link it into the ref chain as if | |
333 | it were a reference | |
334 | */ | |
335 | refize(sp, nlist_p); | |
336 | } | |
337 | else if (sp->scoms_chain) { | |
338 | /* If we have a previous common, keep only the biggest */ | |
339 | if ( (*(sp->scoms_chain))->value > sym->value) { | |
340 | /* other common is bigger, throw this one away */ | |
341 | refize(sp, nlist_p); | |
342 | } | |
343 | else if (sp->scoms_chain != nlist_p) { | |
344 | /* other common is smaller, throw that away */ | |
345 | refize(sp, sp->scoms_chain); | |
346 | sp->scoms_chain = nlist_p; | |
347 | } | |
348 | } | |
349 | else { | |
350 | /* This is the first time we've seen a common, so | |
351 | * remember it - if it was undefined before, we know it's defined now | |
352 | */ | |
353 | if (sp->srefs_chain) | |
354 | undefined_global_sym_count--; | |
355 | ||
356 | commons_pending++; | |
357 | sp->scoms_chain = nlist_p; | |
358 | } | |
359 | } | |
360 | ||
361 | else if (flag_is_defined(this_symbol_flags)) { | |
362 | /* This is the definition of a symbol, add to def chain */ | |
363 | if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) { | |
364 | /* Multiple definition */ | |
365 | asymbol *sy = *(sp->sdefs_chain); | |
366 | lang_input_statement_type *stat = (lang_input_statement_type *) sy->the_bfd->usrdata; | |
367 | lang_input_statement_type *stat1 = (lang_input_statement_type *) sym->the_bfd->usrdata; | |
368 | asymbol ** stat1_symbols = stat1 ? stat1->asymbols: 0; | |
369 | asymbol ** stat_symbols = stat ? stat->asymbols:0; | |
370 | ||
371 | multiple_def_count++; | |
372 | info("%C: multiple definition of `%T'\n", | |
373 | sym->the_bfd, | |
374 | sym->section, | |
375 | stat1_symbols, | |
376 | sym->value, | |
377 | sym); | |
378 | ||
379 | info("%C: first seen here\n", | |
380 | sy->the_bfd, | |
381 | sy->section, | |
382 | stat_symbols, | |
383 | sy->value); | |
384 | } | |
385 | else { | |
386 | sym->udata =(void *)( sp->sdefs_chain); | |
387 | sp->sdefs_chain = nlist_p; | |
388 | } | |
389 | /* A definition overrides a common symbol */ | |
390 | if (sp->scoms_chain) { | |
391 | refize(sp, sp->scoms_chain); | |
392 | sp->scoms_chain = 0; | |
393 | commons_pending--; | |
394 | } | |
395 | else if (sp->srefs_chain) { | |
396 | /* If previously was undefined, then remember as defined */ | |
397 | undefined_global_sym_count--; | |
398 | } | |
399 | } | |
400 | else { | |
401 | if (sp->scoms_chain == (asymbol **)NULL | |
402 | && sp->srefs_chain == (asymbol **)NULL | |
403 | && sp->sdefs_chain == (asymbol **)NULL) { | |
404 | /* And it's the first time we've seen it */ | |
405 | undefined_global_sym_count++; | |
406 | ||
407 | } | |
408 | ||
409 | refize(sp, nlist_p); | |
410 | } | |
411 | ||
412 | ASSERT(sp->sdefs_chain == 0 || sp->scoms_chain == 0); | |
413 | ASSERT(sp->scoms_chain ==0 || (*(sp->scoms_chain))->udata == 0); | |
414 | ||
415 | ||
416 | } | |
417 | ||
418 | static void | |
419 | Q_enter_file_symbols (entry) | |
420 | lang_input_statement_type *entry; | |
421 | { | |
422 | asymbol **q ; | |
423 | entry->common_section = | |
424 | bfd_make_section(entry->the_bfd, "COMMON"); | |
425 | ||
426 | ldlang_add_file(entry); | |
427 | ||
428 | ||
429 | if (trace_files || option_v) { | |
430 | info("%I\n", entry); | |
431 | } | |
432 | ||
433 | total_symbols_seen += entry->symbol_count; | |
434 | total_files_seen ++; | |
435 | for (q = entry->asymbols; *q; q++) | |
436 | { | |
437 | asymbol *p = *q; | |
438 | ||
439 | if (flag_is_undefined_or_global_or_common(p->flags)) | |
440 | { | |
441 | ||
442 | Q_enter_global_ref(q); | |
443 | } | |
444 | ASSERT(p->flags != 0); | |
445 | } | |
446 | } | |
447 | ||
448 | ||
449 | ||
450 | /* Searching libraries */ | |
451 | ||
452 | struct lang_input_statement_struct *decode_library_subfile (); | |
453 | void linear_library (), symdef_library (); | |
454 | ||
455 | /* Search the library ENTRY, already open on descriptor DESC. | |
456 | This means deciding which library members to load, | |
457 | making a chain of `struct lang_input_statement_struct' for those members, | |
458 | and entering their global symbols in the hash table. */ | |
459 | ||
460 | void | |
461 | search_library (entry) | |
462 | struct lang_input_statement_struct *entry; | |
463 | { | |
464 | ||
465 | /* No need to load a library if no undefined symbols */ | |
466 | if (!undefined_global_sym_count) return; | |
467 | ||
468 | if (bfd_has_map(entry->the_bfd)) | |
469 | symdef_library (entry); | |
470 | else | |
471 | linear_library (entry); | |
472 | ||
473 | } | |
474 | ||
475 | ||
476 | void | |
477 | Q_read_file_symbols (entry) | |
478 | struct lang_input_statement_struct *entry; | |
479 | { | |
480 | if (entry->asymbols == (asymbol **)NULL | |
481 | &&entry->real == true | |
482 | && entry->filename != (char *)NULL) | |
483 | { | |
484 | ldfile_open_file (entry); | |
485 | ||
486 | if (bfd_check_format(entry->the_bfd, bfd_object)) | |
487 | { | |
488 | entry->the_bfd->usrdata = (void*)entry; | |
489 | ||
490 | ||
491 | Q_read_entry_symbols (entry->the_bfd, entry); | |
492 | Q_enter_file_symbols (entry); | |
493 | } | |
494 | else if (bfd_check_format(entry->the_bfd, bfd_archive)) | |
495 | { | |
496 | entry->the_bfd->usrdata = (void *)entry; | |
497 | ||
498 | entry->subfiles = (lang_input_statement_type *)NULL; | |
499 | search_library (entry); | |
500 | } | |
501 | else | |
502 | { | |
503 | info("%F%I: malformed input file (not rel or archive) \n", entry); | |
504 | } | |
505 | } | |
506 | ||
507 | } | |
508 | ||
509 | ||
510 | /* Construct and return a lang_input_statement_struct for a library member. | |
511 | The library's lang_input_statement_struct is library_entry, | |
512 | and the library is open on DESC. | |
513 | SUBFILE_OFFSET is the byte index in the library of this member's header. | |
514 | We store the length of the member into *LENGTH_LOC. */ | |
515 | ||
516 | lang_input_statement_type * | |
517 | decode_library_subfile (library_entry, subfile_offset) | |
518 | struct lang_input_statement_struct *library_entry; | |
519 | bfd *subfile_offset; | |
520 | { | |
521 | register struct lang_input_statement_struct *subentry; | |
522 | subentry = (struct lang_input_statement_struct *) ldmalloc (sizeof (struct lang_input_statement_struct)); | |
523 | subentry->filename = subfile_offset -> filename; | |
524 | subentry->local_sym_name = subfile_offset->filename; | |
525 | subentry->asymbols = 0; | |
526 | subentry->the_bfd = subfile_offset; | |
527 | subentry->subfiles = 0; | |
528 | subentry->next = 0; | |
529 | subentry->superfile = library_entry; | |
530 | subentry->is_archive = false; | |
531 | subentry->header_read_flag = false; | |
532 | subentry->just_syms_flag = false; | |
533 | subentry->loaded = false; | |
534 | subentry->chain = 0; | |
535 | ||
536 | return subentry; | |
537 | } | |
538 | ||
539 | boolean subfile_wanted_p (); | |
540 | void | |
541 | clear_syms(entry, offset) | |
542 | struct lang_input_statement_struct *entry; | |
543 | file_ptr offset; | |
544 | { | |
545 | carsym *car; | |
546 | unsigned long indx = bfd_get_next_mapent(entry->the_bfd, | |
547 | BFD_NO_MORE_SYMBOLS, | |
548 | &car); | |
549 | while (indx != BFD_NO_MORE_SYMBOLS) { | |
550 | if (car->file_offset == offset) { | |
551 | car->name = 0; | |
552 | } | |
553 | indx = bfd_get_next_mapent(entry->the_bfd, indx, &car); | |
554 | } | |
555 | ||
556 | } | |
557 | ||
558 | /* Search a library that has a map | |
559 | */ | |
560 | void | |
561 | symdef_library (entry) | |
562 | struct lang_input_statement_struct *entry; | |
563 | ||
564 | { | |
565 | register struct lang_input_statement_struct *prev = 0; | |
566 | ||
567 | boolean not_finished = true; | |
568 | ||
569 | ||
570 | while (not_finished == true) | |
571 | { | |
572 | carsym *exported_library_name; | |
573 | bfd *prev_archive_member_bfd = 0; | |
574 | ||
575 | int idx = bfd_get_next_mapent(entry->the_bfd, | |
576 | BFD_NO_MORE_SYMBOLS, | |
577 | &exported_library_name); | |
578 | ||
579 | not_finished = false; | |
580 | ||
581 | while (idx != BFD_NO_MORE_SYMBOLS && undefined_global_sym_count) | |
582 | { | |
583 | ||
584 | if (exported_library_name->name) | |
585 | { | |
586 | ||
587 | ldsym_type *sp = ldsym_get_soft (exported_library_name->name); | |
588 | ||
589 | /* If we find a symbol that appears to be needed, think carefully | |
590 | about the archive member that the symbol is in. */ | |
591 | /* So - if it exists, and is referenced somewhere and is | |
592 | undefined or */ | |
593 | if (sp && sp->srefs_chain && !sp->sdefs_chain) | |
594 | { | |
595 | bfd *archive_member_bfd = bfd_get_elt_at_index(entry->the_bfd, idx); | |
596 | struct lang_input_statement_struct *archive_member_lang_input_statement_struct; | |
597 | ||
598 | if (archive_member_bfd && bfd_check_format(archive_member_bfd, bfd_object)) | |
599 | { | |
600 | ||
601 | /* Don't think carefully about any archive member | |
602 | more than once in a given pass. */ | |
603 | if (prev_archive_member_bfd != archive_member_bfd) | |
604 | { | |
605 | ||
606 | prev_archive_member_bfd = archive_member_bfd; | |
607 | ||
608 | /* Read the symbol table of the archive member. */ | |
609 | ||
610 | if (archive_member_bfd->usrdata != (void *)NULL) { | |
611 | ||
612 | archive_member_lang_input_statement_struct =(lang_input_statement_type *) archive_member_bfd->usrdata; | |
613 | } | |
614 | else { | |
615 | ||
616 | archive_member_lang_input_statement_struct = | |
617 | decode_library_subfile (entry, archive_member_bfd); | |
618 | archive_member_bfd->usrdata = (void *) archive_member_lang_input_statement_struct; | |
619 | ||
620 | } | |
621 | ||
622 | if (archive_member_lang_input_statement_struct == 0) { | |
623 | info ("%F%I contains invalid archive member %s\n", | |
624 | entry, | |
625 | sp->name); | |
626 | } | |
627 | ||
628 | if (archive_member_lang_input_statement_struct->loaded == false) | |
629 | { | |
630 | ||
631 | Q_read_entry_symbols (archive_member_bfd, archive_member_lang_input_statement_struct); | |
632 | /* Now scan the symbol table and decide whether to load. */ | |
633 | ||
634 | ||
635 | if (subfile_wanted_p (archive_member_lang_input_statement_struct) == true) | |
636 | ||
637 | { | |
638 | /* This member is needed; load it. | |
639 | Since we are loading something on this pass, | |
640 | we must make another pass through the symdef data. */ | |
641 | ||
642 | not_finished = true; | |
643 | ||
644 | Q_enter_file_symbols (archive_member_lang_input_statement_struct); | |
645 | ||
646 | if (prev) | |
647 | prev->chain = archive_member_lang_input_statement_struct; | |
648 | else | |
649 | entry->subfiles = archive_member_lang_input_statement_struct; | |
650 | ||
651 | ||
652 | prev = archive_member_lang_input_statement_struct; | |
653 | ||
654 | ||
655 | /* Clear out this member's symbols from the symdef data | |
656 | so that following passes won't waste time on them. */ | |
657 | clear_syms(entry, exported_library_name->file_offset); | |
658 | archive_member_lang_input_statement_struct->loaded = true; | |
659 | } | |
660 | } | |
661 | } | |
662 | } | |
663 | } | |
664 | } | |
665 | idx = bfd_get_next_mapent(entry->the_bfd, idx, &exported_library_name); | |
666 | } | |
667 | } | |
668 | } | |
669 | ||
670 | void | |
671 | linear_library (entry) | |
672 | struct lang_input_statement_struct *entry; | |
673 | { | |
674 | boolean more_to_do = true; | |
675 | register struct lang_input_statement_struct *prev = 0; | |
676 | ||
677 | while (more_to_do) { | |
678 | ||
679 | bfd * archive = bfd_openr_next_archived_file(entry->the_bfd,0); | |
680 | ||
681 | more_to_do = false; | |
682 | while (archive) { | |
683 | if (bfd_check_format(archive, bfd_object)) | |
684 | { | |
685 | register struct lang_input_statement_struct *subentry; | |
686 | ||
687 | subentry = decode_library_subfile (entry, | |
688 | archive); | |
689 | ||
690 | archive->usrdata = (void *) subentry; | |
691 | if (!subentry) return; | |
692 | if (subentry->loaded == false) { | |
693 | Q_read_entry_symbols (archive, subentry); | |
694 | ||
695 | if (subfile_wanted_p (subentry) == true) | |
696 | { | |
697 | Q_enter_file_symbols (subentry); | |
698 | ||
699 | if (prev) | |
700 | prev->chain = subentry; | |
701 | else | |
702 | entry->subfiles = subentry; | |
703 | prev = subentry; | |
704 | ||
705 | more_to_do = true; | |
706 | subentry->loaded = true; | |
707 | } | |
708 | } | |
709 | } | |
710 | archive = bfd_openr_next_archived_file(entry->the_bfd,archive); | |
711 | ||
712 | } | |
713 | ||
714 | } | |
715 | } | |
716 | ||
717 | /* ENTRY is an entry for a library member. | |
718 | Its symbols have been read into core, but not entered. | |
719 | Return nonzero if we ought to load this member. */ | |
720 | ||
721 | boolean | |
722 | subfile_wanted_p (entry) | |
723 | struct lang_input_statement_struct *entry; | |
724 | { | |
725 | asymbol **q; | |
726 | ||
727 | for (q = entry->asymbols; *q; q++) | |
728 | { | |
729 | asymbol *p = *q; | |
730 | ||
731 | /* If the symbol has an interesting definition, we could | |
732 | potentially want it. */ | |
733 | ||
734 | if (p->flags & BSF_FORT_COMM | |
735 | || p->flags & BSF_GLOBAL) | |
736 | { | |
737 | register ldsym_type *sp = ldsym_get_soft (p->name); | |
738 | ||
739 | ||
740 | /* If this symbol has not been hashed, | |
741 | we can't be looking for it. */ | |
742 | if (sp != (ldsym_type *)NULL | |
743 | && sp->sdefs_chain == (asymbol **)NULL) { | |
744 | if (sp->srefs_chain != (asymbol **)NULL | |
745 | || sp->scoms_chain != (asymbol **)NULL) | |
746 | { | |
747 | /* This is a symbol we are looking for. It is either | |
748 | not yet defined or common. */ | |
749 | ||
750 | if (flag_is_common(p->flags)) | |
751 | { | |
752 | /* This libary member has something to | |
753 | say about this element. We should | |
754 | remember if its a new size */ | |
755 | /* Move something from the ref list to the com list */ | |
756 | if(sp->scoms_chain) { | |
757 | /* Already a common symbol, maybe update it */ | |
758 | if (p->value > (*(sp->scoms_chain))->value) { | |
759 | (*(sp->scoms_chain))->value = p->value; | |
760 | } | |
761 | } | |
762 | else { | |
763 | /* Take a value from the ref chain | |
764 | Here we are moving a symbol from the owning bfd | |
765 | to another bfd. We must set up the | |
766 | common_section portion of the bfd thing */ | |
767 | ||
768 | ||
769 | ||
770 | sp->scoms_chain = sp->srefs_chain; | |
771 | sp->srefs_chain = | |
772 | (asymbol **)((*(sp->srefs_chain))->udata); | |
773 | (*(sp->scoms_chain))->udata = (void*)NULL; | |
774 | ||
775 | (*( sp->scoms_chain))->flags = BSF_FORT_COMM; | |
776 | commons_pending++; | |
777 | undefined_global_sym_count--; | |
778 | } { | |
779 | asymbol *com = *(sp->scoms_chain); | |
780 | if (((lang_input_statement_type *) | |
781 | (com->the_bfd->usrdata))->common_section == | |
782 | (asection *)NULL) { | |
783 | ((lang_input_statement_type *) | |
784 | (com->the_bfd->usrdata))->common_section = | |
785 | bfd_make_section(com->the_bfd, "COMMON"); | |
786 | } | |
787 | } | |
788 | ASSERT(p->udata == 0); | |
789 | } | |
790 | ||
791 | else { | |
792 | if (write_map) | |
793 | { | |
794 | info("%I needed due to %s\n",entry, sp->name); | |
795 | } | |
796 | return true; | |
797 | } | |
798 | } | |
799 | } | |
800 | } | |
801 | } | |
802 | ||
803 | return false; | |
804 | } | |
805 | ||
806 |