1 |
/* linker.c -- BFD linker routines |
/* linker.c -- BFD linker routines |
2 |
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
3 |
Free Software Foundation, Inc. |
2003, 2004, 2005 Free Software Foundation, Inc. |
4 |
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support |
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
11 |
(at your option) any later version. |
(at your option) any later version. |
12 |
|
|
13 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
GNU General Public License for more details. |
17 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
#include "bfd.h" |
#include "bfd.h" |
23 |
#include "sysdep.h" |
#include "sysdep.h" |
88 |
|
|
89 |
For example, with each entry in the hash table the a.out |
For example, with each entry in the hash table the a.out |
90 |
linker keeps the index the symbol has in the final output file |
linker keeps the index the symbol has in the final output file |
91 |
(this index number is used so that when doing a relocateable |
(this index number is used so that when doing a relocatable |
92 |
link the symbol index used in the output file can be quickly |
link the symbol index used in the output file can be quickly |
93 |
filled in when copying over a reloc). The a.out linker code |
filled in when copying over a reloc). The a.out linker code |
94 |
defines the required structures and functions for a hash table |
defines the required structures and functions for a hash table |
200 |
read the symbol information, the <<_bfd_link_add_symbols>> |
read the symbol information, the <<_bfd_link_add_symbols>> |
201 |
routine should save it somewhere attached to the object file |
routine should save it somewhere attached to the object file |
202 |
BFD. However, the information should only be saved if the |
BFD. However, the information should only be saved if the |
203 |
<<keep_memory>> field of the <<info>> argument is true, so |
<<keep_memory>> field of the <<info>> argument is TRUE, so |
204 |
that the <<-no-keep-memory>> linker switch is effective. |
that the <<-no-keep-memory>> linker switch is effective. |
205 |
|
|
206 |
The a.out function which adds symbols from an object file is |
The a.out function which adds symbols from an object file is |
277 |
the input sections and copy the data into the output sections. |
the input sections and copy the data into the output sections. |
278 |
It must build an output symbol table including any local |
It must build an output symbol table including any local |
279 |
symbols from the input files and the global symbols from the |
symbols from the input files and the global symbols from the |
280 |
hash table. When producing relocateable output, it must |
hash table. When producing relocatable output, it must |
281 |
modify the input relocs and write them into the output file. |
modify the input relocs and write them into the output file. |
282 |
There may also be object format dependent work to be done. |
There may also be object format dependent work to be done. |
283 |
|
|
317 |
types of information. They also describe relocs that must be |
types of information. They also describe relocs that must be |
318 |
created by the BFD backend, but do not correspond to any input |
created by the BFD backend, but do not correspond to any input |
319 |
file; this is used to support -Ur, which builds constructors |
file; this is used to support -Ur, which builds constructors |
320 |
while generating a relocateable object file. |
while generating a relocatable object file. |
321 |
|
|
322 |
INODE |
INODE |
323 |
Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link |
Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link |
339 |
input files. The <<_bfd_final_link>> function should read the |
input files. The <<_bfd_final_link>> function should read the |
340 |
contents of the section and any associated relocs, apply the |
contents of the section and any associated relocs, apply the |
341 |
relocs to the section contents, and write out the modified |
relocs to the section contents, and write out the modified |
342 |
section contents. If performing a relocateable link, the |
section contents. If performing a relocatable link, the |
343 |
relocs themselves must also be modified and written out. |
relocs themselves must also be modified and written out. |
344 |
|
|
345 |
@findex _bfd_relocate_contents |
@findex _bfd_relocate_contents |
406 |
file at the end of <<NAME(aout,final_link)>>. |
file at the end of <<NAME(aout,final_link)>>. |
407 |
*/ |
*/ |
408 |
|
|
409 |
static boolean generic_link_read_symbols |
static bfd_boolean generic_link_add_object_symbols |
410 |
PARAMS ((bfd *)); |
(bfd *, struct bfd_link_info *, bfd_boolean collect); |
411 |
static boolean generic_link_add_symbols |
static bfd_boolean generic_link_add_symbols |
412 |
PARAMS ((bfd *, struct bfd_link_info *, boolean collect)); |
(bfd *, struct bfd_link_info *, bfd_boolean); |
413 |
static boolean generic_link_add_object_symbols |
static bfd_boolean generic_link_check_archive_element_no_collect |
414 |
PARAMS ((bfd *, struct bfd_link_info *, boolean collect)); |
(bfd *, struct bfd_link_info *, bfd_boolean *); |
415 |
static boolean generic_link_check_archive_element_no_collect |
static bfd_boolean generic_link_check_archive_element_collect |
416 |
PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); |
(bfd *, struct bfd_link_info *, bfd_boolean *); |
417 |
static boolean generic_link_check_archive_element_collect |
static bfd_boolean generic_link_check_archive_element |
418 |
PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); |
(bfd *, struct bfd_link_info *, bfd_boolean *, bfd_boolean); |
419 |
static boolean generic_link_check_archive_element |
static bfd_boolean generic_link_add_symbol_list |
420 |
PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded, boolean collect)); |
(bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **, |
421 |
static boolean generic_link_add_symbol_list |
bfd_boolean); |
422 |
PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **, |
static bfd_boolean generic_add_output_symbol |
423 |
boolean collect)); |
(bfd *, size_t *psymalloc, asymbol *); |
424 |
static bfd *hash_entry_bfd PARAMS ((struct bfd_link_hash_entry *)); |
static bfd_boolean default_data_link_order |
425 |
static void set_symbol_from_hash |
(bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *); |
426 |
PARAMS ((asymbol *, struct bfd_link_hash_entry *)); |
static bfd_boolean default_indirect_link_order |
427 |
static boolean generic_add_output_symbol |
(bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *, |
428 |
PARAMS ((bfd *, size_t *psymalloc, asymbol *)); |
bfd_boolean); |
|
static boolean default_data_link_order |
|
|
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
|
|
struct bfd_link_order *)); |
|
|
static boolean default_indirect_link_order |
|
|
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
|
|
struct bfd_link_order *, boolean)); |
|
429 |
|
|
430 |
/* The link hash table structure is defined in bfdlink.h. It provides |
/* The link hash table structure is defined in bfdlink.h. It provides |
431 |
a base hash table which the backend specific hash tables are built |
a base hash table which the backend specific hash tables are built |
434 |
/* Routine to create an entry in the link hash table. */ |
/* Routine to create an entry in the link hash table. */ |
435 |
|
|
436 |
struct bfd_hash_entry * |
struct bfd_hash_entry * |
437 |
_bfd_link_hash_newfunc (entry, table, string) |
_bfd_link_hash_newfunc (struct bfd_hash_entry *entry, |
438 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *table, |
439 |
struct bfd_hash_table *table; |
const char *string) |
|
const char *string; |
|
440 |
{ |
{ |
441 |
/* Allocate the structure if it has not already been allocated by a |
/* Allocate the structure if it has not already been allocated by a |
442 |
subclass. */ |
subclass. */ |
455 |
|
|
456 |
/* Initialize the local fields. */ |
/* Initialize the local fields. */ |
457 |
h->type = bfd_link_hash_new; |
h->type = bfd_link_hash_new; |
458 |
h->next = NULL; |
memset (&h->u.undef.next, 0, |
459 |
|
(sizeof (struct bfd_link_hash_entry) |
460 |
|
- offsetof (struct bfd_link_hash_entry, u.undef.next))); |
461 |
} |
} |
462 |
|
|
463 |
return entry; |
return entry; |
466 |
/* Initialize a link hash table. The BFD argument is the one |
/* Initialize a link hash table. The BFD argument is the one |
467 |
responsible for creating this table. */ |
responsible for creating this table. */ |
468 |
|
|
469 |
boolean |
bfd_boolean |
470 |
_bfd_link_hash_table_init (table, abfd, newfunc) |
_bfd_link_hash_table_init |
471 |
struct bfd_link_hash_table *table; |
(struct bfd_link_hash_table *table, |
472 |
bfd *abfd; |
bfd *abfd, |
473 |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, |
474 |
struct bfd_hash_table *, |
struct bfd_hash_table *, |
475 |
const char *)); |
const char *)) |
476 |
{ |
{ |
477 |
table->creator = abfd->xvec; |
table->creator = abfd->xvec; |
478 |
table->undefs = NULL; |
table->undefs = NULL; |
482 |
return bfd_hash_table_init (&table->table, newfunc); |
return bfd_hash_table_init (&table->table, newfunc); |
483 |
} |
} |
484 |
|
|
485 |
/* Look up a symbol in a link hash table. If follow is true, we |
/* Look up a symbol in a link hash table. If follow is TRUE, we |
486 |
follow bfd_link_hash_indirect and bfd_link_hash_warning links to |
follow bfd_link_hash_indirect and bfd_link_hash_warning links to |
487 |
the real symbol. */ |
the real symbol. */ |
488 |
|
|
489 |
struct bfd_link_hash_entry * |
struct bfd_link_hash_entry * |
490 |
bfd_link_hash_lookup (table, string, create, copy, follow) |
bfd_link_hash_lookup (struct bfd_link_hash_table *table, |
491 |
struct bfd_link_hash_table *table; |
const char *string, |
492 |
const char *string; |
bfd_boolean create, |
493 |
boolean create; |
bfd_boolean copy, |
494 |
boolean copy; |
bfd_boolean follow) |
|
boolean follow; |
|
495 |
{ |
{ |
496 |
struct bfd_link_hash_entry *ret; |
struct bfd_link_hash_entry *ret; |
497 |
|
|
498 |
ret = ((struct bfd_link_hash_entry *) |
ret = ((struct bfd_link_hash_entry *) |
499 |
bfd_hash_lookup (&table->table, string, create, copy)); |
bfd_hash_lookup (&table->table, string, create, copy)); |
500 |
|
|
501 |
if (follow && ret != (struct bfd_link_hash_entry *) NULL) |
if (follow && ret != NULL) |
502 |
{ |
{ |
503 |
while (ret->type == bfd_link_hash_indirect |
while (ret->type == bfd_link_hash_indirect |
504 |
|| ret->type == bfd_link_hash_warning) |
|| ret->type == bfd_link_hash_warning) |
513 |
undefined symbol, not for definitions of a symbol. */ |
undefined symbol, not for definitions of a symbol. */ |
514 |
|
|
515 |
struct bfd_link_hash_entry * |
struct bfd_link_hash_entry * |
516 |
bfd_wrapped_link_hash_lookup (abfd, info, string, create, copy, follow) |
bfd_wrapped_link_hash_lookup (bfd *abfd, |
517 |
bfd *abfd; |
struct bfd_link_info *info, |
518 |
struct bfd_link_info *info; |
const char *string, |
519 |
const char *string; |
bfd_boolean create, |
520 |
boolean create; |
bfd_boolean copy, |
521 |
boolean copy; |
bfd_boolean follow) |
|
boolean follow; |
|
522 |
{ |
{ |
523 |
bfd_size_type amt; |
bfd_size_type amt; |
524 |
|
|
525 |
if (info->wrap_hash != NULL) |
if (info->wrap_hash != NULL) |
526 |
{ |
{ |
527 |
const char *l; |
const char *l; |
528 |
|
char prefix = '\0'; |
529 |
|
|
530 |
l = string; |
l = string; |
531 |
if (*l == bfd_get_symbol_leading_char (abfd)) |
if (*l == bfd_get_symbol_leading_char (abfd) || *l == info->wrap_char) |
532 |
++l; |
{ |
533 |
|
prefix = *l; |
534 |
|
++l; |
535 |
|
} |
536 |
|
|
537 |
#undef WRAP |
#undef WRAP |
538 |
#define WRAP "__wrap_" |
#define WRAP "__wrap_" |
539 |
|
|
540 |
if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL) |
if (bfd_hash_lookup (info->wrap_hash, l, FALSE, FALSE) != NULL) |
541 |
{ |
{ |
542 |
char *n; |
char *n; |
543 |
struct bfd_link_hash_entry *h; |
struct bfd_link_hash_entry *h; |
546 |
references to SYM with references to __wrap_SYM. */ |
references to SYM with references to __wrap_SYM. */ |
547 |
|
|
548 |
amt = strlen (l) + sizeof WRAP + 1; |
amt = strlen (l) + sizeof WRAP + 1; |
549 |
n = (char *) bfd_malloc (amt); |
n = bfd_malloc (amt); |
550 |
if (n == NULL) |
if (n == NULL) |
551 |
return NULL; |
return NULL; |
552 |
|
|
553 |
/* Note that symbol_leading_char may be '\0'. */ |
n[0] = prefix; |
|
n[0] = bfd_get_symbol_leading_char (abfd); |
|
554 |
n[1] = '\0'; |
n[1] = '\0'; |
555 |
strcat (n, WRAP); |
strcat (n, WRAP); |
556 |
strcat (n, l); |
strcat (n, l); |
557 |
h = bfd_link_hash_lookup (info->hash, n, create, true, follow); |
h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow); |
558 |
free (n); |
free (n); |
559 |
return h; |
return h; |
560 |
} |
} |
567 |
if (*l == '_' |
if (*l == '_' |
568 |
&& strncmp (l, REAL, sizeof REAL - 1) == 0 |
&& strncmp (l, REAL, sizeof REAL - 1) == 0 |
569 |
&& bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1, |
&& bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1, |
570 |
false, false) != NULL) |
FALSE, FALSE) != NULL) |
571 |
{ |
{ |
572 |
char *n; |
char *n; |
573 |
struct bfd_link_hash_entry *h; |
struct bfd_link_hash_entry *h; |
577 |
with references to SYM. */ |
with references to SYM. */ |
578 |
|
|
579 |
amt = strlen (l + sizeof REAL - 1) + 2; |
amt = strlen (l + sizeof REAL - 1) + 2; |
580 |
n = (char *) bfd_malloc (amt); |
n = bfd_malloc (amt); |
581 |
if (n == NULL) |
if (n == NULL) |
582 |
return NULL; |
return NULL; |
583 |
|
|
584 |
/* Note that symbol_leading_char may be '\0'. */ |
n[0] = prefix; |
|
n[0] = bfd_get_symbol_leading_char (abfd); |
|
585 |
n[1] = '\0'; |
n[1] = '\0'; |
586 |
strcat (n, l + sizeof REAL - 1); |
strcat (n, l + sizeof REAL - 1); |
587 |
h = bfd_link_hash_lookup (info->hash, n, create, true, follow); |
h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow); |
588 |
free (n); |
free (n); |
589 |
return h; |
return h; |
590 |
} |
} |
602 |
call. */ |
call. */ |
603 |
|
|
604 |
void |
void |
605 |
bfd_link_hash_traverse (table, func, info) |
bfd_link_hash_traverse |
606 |
struct bfd_link_hash_table *table; |
(struct bfd_link_hash_table *table, |
607 |
boolean (*func) PARAMS ((struct bfd_link_hash_entry *, PTR)); |
bfd_boolean (*func) (struct bfd_link_hash_entry *, void *), |
608 |
PTR info; |
void *info) |
609 |
{ |
{ |
610 |
bfd_hash_traverse (&table->table, |
bfd_hash_traverse (&table->table, |
611 |
((boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) |
(bfd_boolean (*) (struct bfd_hash_entry *, void *)) func, |
|
func), |
|
612 |
info); |
info); |
613 |
} |
} |
614 |
|
|
615 |
/* Add a symbol to the linker hash table undefs list. */ |
/* Add a symbol to the linker hash table undefs list. */ |
616 |
|
|
617 |
INLINE void |
void |
618 |
bfd_link_add_undef (table, h) |
bfd_link_add_undef (struct bfd_link_hash_table *table, |
619 |
struct bfd_link_hash_table *table; |
struct bfd_link_hash_entry *h) |
620 |
struct bfd_link_hash_entry *h; |
{ |
621 |
{ |
BFD_ASSERT (h->u.undef.next == NULL); |
622 |
BFD_ASSERT (h->next == NULL); |
if (table->undefs_tail != NULL) |
623 |
if (table->undefs_tail != (struct bfd_link_hash_entry *) NULL) |
table->undefs_tail->u.undef.next = h; |
624 |
table->undefs_tail->next = h; |
if (table->undefs == NULL) |
|
if (table->undefs == (struct bfd_link_hash_entry *) NULL) |
|
625 |
table->undefs = h; |
table->undefs = h; |
626 |
table->undefs_tail = h; |
table->undefs_tail = h; |
627 |
} |
} |
628 |
|
|
629 |
|
/* The undefs list was designed so that in normal use we don't need to |
630 |
|
remove entries. However, if symbols on the list are changed from |
631 |
|
bfd_link_hash_undefined to either bfd_link_hash_undefweak or |
632 |
|
bfd_link_hash_new for some reason, then they must be removed from the |
633 |
|
list. Failure to do so might result in the linker attempting to add |
634 |
|
the symbol to the list again at a later stage. */ |
635 |
|
|
636 |
|
void |
637 |
|
bfd_link_repair_undef_list (struct bfd_link_hash_table *table) |
638 |
|
{ |
639 |
|
struct bfd_link_hash_entry **pun; |
640 |
|
|
641 |
|
pun = &table->undefs; |
642 |
|
while (*pun != NULL) |
643 |
|
{ |
644 |
|
struct bfd_link_hash_entry *h = *pun; |
645 |
|
|
646 |
|
if (h->type == bfd_link_hash_new |
647 |
|
|| h->type == bfd_link_hash_undefweak) |
648 |
|
{ |
649 |
|
*pun = h->u.undef.next; |
650 |
|
h->u.undef.next = NULL; |
651 |
|
if (h == table->undefs_tail) |
652 |
|
{ |
653 |
|
if (pun == &table->undefs) |
654 |
|
table->undefs_tail = NULL; |
655 |
|
else |
656 |
|
/* pun points at an u.undef.next field. Go back to |
657 |
|
the start of the link_hash_entry. */ |
658 |
|
table->undefs_tail = (struct bfd_link_hash_entry *) |
659 |
|
((char *) pun - ((char *) &h->u.undef.next - (char *) h)); |
660 |
|
break; |
661 |
|
} |
662 |
|
} |
663 |
|
else |
664 |
|
pun = &h->u.undef.next; |
665 |
|
} |
666 |
|
} |
667 |
|
|
668 |
/* Routine to create an entry in an generic link hash table. */ |
/* Routine to create an entry in a generic link hash table. */ |
669 |
|
|
670 |
struct bfd_hash_entry * |
struct bfd_hash_entry * |
671 |
_bfd_generic_link_hash_newfunc (entry, table, string) |
_bfd_generic_link_hash_newfunc (struct bfd_hash_entry *entry, |
672 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *table, |
673 |
struct bfd_hash_table *table; |
const char *string) |
|
const char *string; |
|
674 |
{ |
{ |
675 |
/* Allocate the structure if it has not already been allocated by a |
/* Allocate the structure if it has not already been allocated by a |
676 |
subclass. */ |
subclass. */ |
677 |
if (entry == NULL) |
if (entry == NULL) |
678 |
{ |
{ |
679 |
entry = bfd_hash_allocate (table, |
entry = |
680 |
sizeof (struct generic_link_hash_entry)); |
bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)); |
681 |
if (entry == NULL) |
if (entry == NULL) |
682 |
return entry; |
return entry; |
683 |
} |
} |
690 |
|
|
691 |
/* Set local fields. */ |
/* Set local fields. */ |
692 |
ret = (struct generic_link_hash_entry *) entry; |
ret = (struct generic_link_hash_entry *) entry; |
693 |
ret->written = false; |
ret->written = FALSE; |
694 |
ret->sym = NULL; |
ret->sym = NULL; |
695 |
} |
} |
696 |
|
|
697 |
return entry; |
return entry; |
698 |
} |
} |
699 |
|
|
700 |
/* Create an generic link hash table. */ |
/* Create a generic link hash table. */ |
701 |
|
|
702 |
struct bfd_link_hash_table * |
struct bfd_link_hash_table * |
703 |
_bfd_generic_link_hash_table_create (abfd) |
_bfd_generic_link_hash_table_create (bfd *abfd) |
|
bfd *abfd; |
|
704 |
{ |
{ |
705 |
struct generic_link_hash_table *ret; |
struct generic_link_hash_table *ret; |
706 |
bfd_size_type amt = sizeof (struct generic_link_hash_table); |
bfd_size_type amt = sizeof (struct generic_link_hash_table); |
707 |
|
|
708 |
ret = (struct generic_link_hash_table *) bfd_malloc (amt); |
ret = bfd_malloc (amt); |
709 |
if (ret == NULL) |
if (ret == NULL) |
710 |
return (struct bfd_link_hash_table *) NULL; |
return NULL; |
711 |
if (! _bfd_link_hash_table_init (&ret->root, abfd, |
if (! _bfd_link_hash_table_init (&ret->root, abfd, |
712 |
_bfd_generic_link_hash_newfunc)) |
_bfd_generic_link_hash_newfunc)) |
713 |
{ |
{ |
714 |
free (ret); |
free (ret); |
715 |
return (struct bfd_link_hash_table *) NULL; |
return NULL; |
716 |
} |
} |
717 |
return &ret->root; |
return &ret->root; |
718 |
} |
} |
719 |
|
|
720 |
void |
void |
721 |
_bfd_generic_link_hash_table_free (hash) |
_bfd_generic_link_hash_table_free (struct bfd_link_hash_table *hash) |
|
struct bfd_link_hash_table *hash; |
|
722 |
{ |
{ |
723 |
struct generic_link_hash_table *ret |
struct generic_link_hash_table *ret |
724 |
= (struct generic_link_hash_table *) hash; |
= (struct generic_link_hash_table *) hash; |
734 |
the hash table pointing to different instances of the symbol |
the hash table pointing to different instances of the symbol |
735 |
structure. */ |
structure. */ |
736 |
|
|
737 |
static boolean |
static bfd_boolean |
738 |
generic_link_read_symbols (abfd) |
generic_link_read_symbols (bfd *abfd) |
|
bfd *abfd; |
|
739 |
{ |
{ |
740 |
if (bfd_get_outsymbols (abfd) == (asymbol **) NULL) |
if (bfd_get_outsymbols (abfd) == NULL) |
741 |
{ |
{ |
742 |
long symsize; |
long symsize; |
743 |
long symcount; |
long symcount; |
744 |
|
|
745 |
symsize = bfd_get_symtab_upper_bound (abfd); |
symsize = bfd_get_symtab_upper_bound (abfd); |
746 |
if (symsize < 0) |
if (symsize < 0) |
747 |
return false; |
return FALSE; |
748 |
bfd_get_outsymbols (abfd) = |
bfd_get_outsymbols (abfd) = bfd_alloc (abfd, symsize); |
|
(asymbol **) bfd_alloc (abfd, (bfd_size_type) symsize); |
|
749 |
if (bfd_get_outsymbols (abfd) == NULL && symsize != 0) |
if (bfd_get_outsymbols (abfd) == NULL && symsize != 0) |
750 |
return false; |
return FALSE; |
751 |
symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd)); |
symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd)); |
752 |
if (symcount < 0) |
if (symcount < 0) |
753 |
return false; |
return FALSE; |
754 |
bfd_get_symcount (abfd) = symcount; |
bfd_get_symcount (abfd) = symcount; |
755 |
} |
} |
756 |
|
|
757 |
return true; |
return TRUE; |
758 |
} |
} |
759 |
|
|
760 |
/* Generic function to add symbols to from an object file to the |
/* Generic function to add symbols to from an object file to the |
761 |
global hash table. This version does not automatically collect |
global hash table. This version does not automatically collect |
762 |
constructors by name. */ |
constructors by name. */ |
763 |
|
|
764 |
boolean |
bfd_boolean |
765 |
_bfd_generic_link_add_symbols (abfd, info) |
_bfd_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
766 |
{ |
{ |
767 |
return generic_link_add_symbols (abfd, info, false); |
return generic_link_add_symbols (abfd, info, FALSE); |
768 |
} |
} |
769 |
|
|
770 |
/* Generic function to add symbols from an object file to the global |
/* Generic function to add symbols from an object file to the global |
774 |
constructors and destructors; these are approximately those targets |
constructors and destructors; these are approximately those targets |
775 |
for which gcc uses collect2 and do not support stabs. */ |
for which gcc uses collect2 and do not support stabs. */ |
776 |
|
|
777 |
boolean |
bfd_boolean |
778 |
_bfd_generic_link_add_symbols_collect (abfd, info) |
_bfd_generic_link_add_symbols_collect (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
779 |
{ |
{ |
780 |
return generic_link_add_symbols (abfd, info, true); |
return generic_link_add_symbols (abfd, info, TRUE); |
781 |
} |
} |
782 |
|
|
783 |
/* Indicate that we are only retrieving symbol values from this |
/* Indicate that we are only retrieving symbol values from this |
785 |
file are absolute. */ |
file are absolute. */ |
786 |
|
|
787 |
void |
void |
788 |
_bfd_generic_link_just_syms (sec, info) |
_bfd_generic_link_just_syms (asection *sec, |
789 |
asection *sec; |
struct bfd_link_info *info ATTRIBUTE_UNUSED) |
|
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
|
790 |
{ |
{ |
791 |
sec->output_section = bfd_abs_section_ptr; |
sec->output_section = bfd_abs_section_ptr; |
792 |
sec->output_offset = sec->vma; |
sec->output_offset = sec->vma; |
794 |
|
|
795 |
/* Add symbols from an object file to the global hash table. */ |
/* Add symbols from an object file to the global hash table. */ |
796 |
|
|
797 |
static boolean |
static bfd_boolean |
798 |
generic_link_add_symbols (abfd, info, collect) |
generic_link_add_symbols (bfd *abfd, |
799 |
bfd *abfd; |
struct bfd_link_info *info, |
800 |
struct bfd_link_info *info; |
bfd_boolean collect) |
|
boolean collect; |
|
801 |
{ |
{ |
802 |
boolean ret; |
bfd_boolean ret; |
803 |
|
|
804 |
switch (bfd_get_format (abfd)) |
switch (bfd_get_format (abfd)) |
805 |
{ |
{ |
815 |
break; |
break; |
816 |
default: |
default: |
817 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
818 |
ret = false; |
ret = FALSE; |
819 |
} |
} |
820 |
|
|
821 |
return ret; |
return ret; |
823 |
|
|
824 |
/* Add symbols from an object file to the global hash table. */ |
/* Add symbols from an object file to the global hash table. */ |
825 |
|
|
826 |
static boolean |
static bfd_boolean |
827 |
generic_link_add_object_symbols (abfd, info, collect) |
generic_link_add_object_symbols (bfd *abfd, |
828 |
bfd *abfd; |
struct bfd_link_info *info, |
829 |
struct bfd_link_info *info; |
bfd_boolean collect) |
|
boolean collect; |
|
830 |
{ |
{ |
831 |
bfd_size_type symcount; |
bfd_size_type symcount; |
832 |
struct symbol_cache_entry **outsyms; |
struct bfd_symbol **outsyms; |
833 |
|
|
834 |
if (! generic_link_read_symbols (abfd)) |
if (! generic_link_read_symbols (abfd)) |
835 |
return false; |
return FALSE; |
836 |
symcount = _bfd_generic_link_get_symcount (abfd); |
symcount = _bfd_generic_link_get_symcount (abfd); |
837 |
outsyms = _bfd_generic_link_get_symbols (abfd); |
outsyms = _bfd_generic_link_get_symbols (abfd); |
838 |
return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect); |
return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect); |
865 |
struct bfd_hash_table table; |
struct bfd_hash_table table; |
866 |
}; |
}; |
867 |
|
|
|
static struct bfd_hash_entry *archive_hash_newfunc |
|
|
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
|
|
static boolean archive_hash_table_init |
|
|
PARAMS ((struct archive_hash_table *, |
|
|
struct bfd_hash_entry *(*) (struct bfd_hash_entry *, |
|
|
struct bfd_hash_table *, |
|
|
const char *))); |
|
|
|
|
868 |
/* Create a new entry for an archive hash table. */ |
/* Create a new entry for an archive hash table. */ |
869 |
|
|
870 |
static struct bfd_hash_entry * |
static struct bfd_hash_entry * |
871 |
archive_hash_newfunc (entry, table, string) |
archive_hash_newfunc (struct bfd_hash_entry *entry, |
872 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *table, |
873 |
struct bfd_hash_table *table; |
const char *string) |
|
const char *string; |
|
874 |
{ |
{ |
875 |
struct archive_hash_entry *ret = (struct archive_hash_entry *) entry; |
struct archive_hash_entry *ret = (struct archive_hash_entry *) entry; |
876 |
|
|
877 |
/* Allocate the structure if it has not already been allocated by a |
/* Allocate the structure if it has not already been allocated by a |
878 |
subclass. */ |
subclass. */ |
879 |
if (ret == (struct archive_hash_entry *) NULL) |
if (ret == NULL) |
880 |
ret = ((struct archive_hash_entry *) |
ret = bfd_hash_allocate (table, sizeof (struct archive_hash_entry)); |
881 |
bfd_hash_allocate (table, sizeof (struct archive_hash_entry))); |
if (ret == NULL) |
|
if (ret == (struct archive_hash_entry *) NULL) |
|
882 |
return NULL; |
return NULL; |
883 |
|
|
884 |
/* Call the allocation method of the superclass. */ |
/* Call the allocation method of the superclass. */ |
888 |
if (ret) |
if (ret) |
889 |
{ |
{ |
890 |
/* Initialize the local fields. */ |
/* Initialize the local fields. */ |
891 |
ret->defs = (struct archive_list *) NULL; |
ret->defs = NULL; |
892 |
} |
} |
893 |
|
|
894 |
return (struct bfd_hash_entry *) ret; |
return &ret->root; |
895 |
} |
} |
896 |
|
|
897 |
/* Initialize an archive hash table. */ |
/* Initialize an archive hash table. */ |
898 |
|
|
899 |
static boolean |
static bfd_boolean |
900 |
archive_hash_table_init (table, newfunc) |
archive_hash_table_init |
901 |
struct archive_hash_table *table; |
(struct archive_hash_table *table, |
902 |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, |
903 |
struct bfd_hash_table *, |
struct bfd_hash_table *, |
904 |
const char *)); |
const char *)) |
905 |
{ |
{ |
906 |
return bfd_hash_table_init (&table->table, newfunc); |
return bfd_hash_table_init (&table->table, newfunc); |
907 |
} |
} |
936 |
re-search the symbol table each time a new object file was added. |
re-search the symbol table each time a new object file was added. |
937 |
|
|
938 |
The CHECKFN argument is used to see if an object file should be |
The CHECKFN argument is used to see if an object file should be |
939 |
included. CHECKFN should set *PNEEDED to true if the object file |
included. CHECKFN should set *PNEEDED to TRUE if the object file |
940 |
should be included, and must also call the bfd_link_info |
should be included, and must also call the bfd_link_info |
941 |
add_archive_element callback function and handle adding the symbols |
add_archive_element callback function and handle adding the symbols |
942 |
to the global hash table. CHECKFN should only return false if some |
to the global hash table. CHECKFN should only return FALSE if some |
943 |
sort of error occurs. |
sort of error occurs. |
944 |
|
|
945 |
For some formats, such as a.out, it is possible to look through an |
For some formats, such as a.out, it is possible to look through an |
953 |
may create new undefined symbols which cause a previously examined |
may create new undefined symbols which cause a previously examined |
954 |
object file to be included. */ |
object file to be included. */ |
955 |
|
|
956 |
boolean |
bfd_boolean |
957 |
_bfd_generic_link_add_archive_symbols (abfd, info, checkfn) |
_bfd_generic_link_add_archive_symbols |
958 |
bfd *abfd; |
(bfd *abfd, |
959 |
struct bfd_link_info *info; |
struct bfd_link_info *info, |
960 |
boolean (*checkfn) PARAMS ((bfd *, struct bfd_link_info *, |
bfd_boolean (*checkfn) (bfd *, struct bfd_link_info *, bfd_boolean *)) |
|
boolean *pneeded)); |
|
961 |
{ |
{ |
962 |
carsym *arsyms; |
carsym *arsyms; |
963 |
carsym *arsym_end; |
carsym *arsym_end; |
970 |
if (! bfd_has_map (abfd)) |
if (! bfd_has_map (abfd)) |
971 |
{ |
{ |
972 |
/* An empty archive is a special case. */ |
/* An empty archive is a special case. */ |
973 |
if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL) |
if (bfd_openr_next_archived_file (abfd, NULL) == NULL) |
974 |
return true; |
return TRUE; |
975 |
bfd_set_error (bfd_error_no_armap); |
bfd_set_error (bfd_error_no_armap); |
976 |
return false; |
return FALSE; |
977 |
} |
} |
978 |
|
|
979 |
arsyms = bfd_ardata (abfd)->symdefs; |
arsyms = bfd_ardata (abfd)->symdefs; |
982 |
/* In order to quickly determine whether an symbol is defined in |
/* In order to quickly determine whether an symbol is defined in |
983 |
this archive, we build a hash table of the symbols. */ |
this archive, we build a hash table of the symbols. */ |
984 |
if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc)) |
if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc)) |
985 |
return false; |
return FALSE; |
986 |
for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++) |
for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++) |
987 |
{ |
{ |
988 |
struct archive_hash_entry *arh; |
struct archive_hash_entry *arh; |
989 |
struct archive_list *l, **pp; |
struct archive_list *l, **pp; |
990 |
|
|
991 |
arh = archive_hash_lookup (&arsym_hash, arsym->name, true, false); |
arh = archive_hash_lookup (&arsym_hash, arsym->name, TRUE, FALSE); |
992 |
if (arh == (struct archive_hash_entry *) NULL) |
if (arh == NULL) |
993 |
goto error_return; |
goto error_return; |
994 |
l = ((struct archive_list *) |
l = ((struct archive_list *) |
995 |
archive_hash_allocate (&arsym_hash, sizeof (struct archive_list))); |
archive_hash_allocate (&arsym_hash, sizeof (struct archive_list))); |
996 |
if (l == NULL) |
if (l == NULL) |
997 |
goto error_return; |
goto error_return; |
998 |
l->indx = indx; |
l->indx = indx; |
999 |
for (pp = &arh->defs; |
for (pp = &arh->defs; *pp != NULL; pp = &(*pp)->next) |
|
*pp != (struct archive_list *) NULL; |
|
|
pp = &(*pp)->next) |
|
1000 |
; |
; |
1001 |
*pp = l; |
*pp = l; |
1002 |
l->next = NULL; |
l->next = NULL; |
1010 |
/* New undefined symbols are added to the end of the list, so we |
/* New undefined symbols are added to the end of the list, so we |
1011 |
only need to look through it once. */ |
only need to look through it once. */ |
1012 |
pundef = &info->hash->undefs; |
pundef = &info->hash->undefs; |
1013 |
while (*pundef != (struct bfd_link_hash_entry *) NULL) |
while (*pundef != NULL) |
1014 |
{ |
{ |
1015 |
struct bfd_link_hash_entry *h; |
struct bfd_link_hash_entry *h; |
1016 |
struct archive_hash_entry *arh; |
struct archive_hash_entry *arh; |
1031 |
us to lose track of whether the symbol has been |
us to lose track of whether the symbol has been |
1032 |
referenced). */ |
referenced). */ |
1033 |
if (*pundef != info->hash->undefs_tail) |
if (*pundef != info->hash->undefs_tail) |
1034 |
*pundef = (*pundef)->next; |
*pundef = (*pundef)->u.undef.next; |
1035 |
else |
else |
1036 |
pundef = &(*pundef)->next; |
pundef = &(*pundef)->u.undef.next; |
1037 |
continue; |
continue; |
1038 |
} |
} |
1039 |
|
|
1040 |
/* Look for this symbol in the archive symbol map. */ |
/* Look for this symbol in the archive symbol map. */ |
1041 |
arh = archive_hash_lookup (&arsym_hash, h->root.string, false, false); |
arh = archive_hash_lookup (&arsym_hash, h->root.string, FALSE, FALSE); |
1042 |
if (arh == (struct archive_hash_entry *) NULL) |
if (arh == NULL) |
1043 |
{ |
{ |
1044 |
/* If we haven't found the exact symbol we're looking for, |
/* If we haven't found the exact symbol we're looking for, |
1045 |
let's look for its import thunk */ |
let's look for its import thunk */ |
1046 |
if (info->pei386_auto_import) |
if (info->pei386_auto_import) |
1047 |
{ |
{ |
1048 |
bfd_size_type amt = strlen (h->root.string) + 10; |
bfd_size_type amt = strlen (h->root.string) + 10; |
1049 |
char *buf = (char *) bfd_malloc (amt); |
char *buf = bfd_malloc (amt); |
1050 |
if (buf == NULL) |
if (buf == NULL) |
1051 |
return false; |
return FALSE; |
1052 |
|
|
1053 |
sprintf (buf, "__imp_%s", h->root.string); |
sprintf (buf, "__imp_%s", h->root.string); |
1054 |
arh = archive_hash_lookup (&arsym_hash, buf, false, false); |
arh = archive_hash_lookup (&arsym_hash, buf, FALSE, FALSE); |
1055 |
free(buf); |
free(buf); |
1056 |
} |
} |
1057 |
if (arh == (struct archive_hash_entry *) NULL) |
if (arh == NULL) |
1058 |
{ |
{ |
1059 |
pundef = &(*pundef)->next; |
pundef = &(*pundef)->u.undef.next; |
1060 |
continue; |
continue; |
1061 |
} |
} |
1062 |
} |
} |
1063 |
/* Look at all the objects which define this symbol. */ |
/* Look at all the objects which define this symbol. */ |
1064 |
for (l = arh->defs; l != (struct archive_list *) NULL; l = l->next) |
for (l = arh->defs; l != NULL; l = l->next) |
1065 |
{ |
{ |
1066 |
bfd *element; |
bfd *element; |
1067 |
boolean needed; |
bfd_boolean needed; |
1068 |
|
|
1069 |
/* If the symbol has gotten defined along the way, quit. */ |
/* If the symbol has gotten defined along the way, quit. */ |
1070 |
if (h->type != bfd_link_hash_undefined |
if (h->type != bfd_link_hash_undefined |
1072 |
break; |
break; |
1073 |
|
|
1074 |
element = bfd_get_elt_at_index (abfd, l->indx); |
element = bfd_get_elt_at_index (abfd, l->indx); |
1075 |
if (element == (bfd *) NULL) |
if (element == NULL) |
1076 |
goto error_return; |
goto error_return; |
1077 |
|
|
1078 |
/* If we've already included this element, or if we've |
/* If we've already included this element, or if we've |
1105 |
} |
} |
1106 |
} |
} |
1107 |
|
|
1108 |
pundef = &(*pundef)->next; |
pundef = &(*pundef)->u.undef.next; |
1109 |
} |
} |
1110 |
|
|
1111 |
archive_hash_table_free (&arsym_hash); |
archive_hash_table_free (&arsym_hash); |
1113 |
/* Save PASS in case we are called again. */ |
/* Save PASS in case we are called again. */ |
1114 |
abfd->archive_pass = pass; |
abfd->archive_pass = pass; |
1115 |
|
|
1116 |
return true; |
return TRUE; |
1117 |
|
|
1118 |
error_return: |
error_return: |
1119 |
archive_hash_table_free (&arsym_hash); |
archive_hash_table_free (&arsym_hash); |
1120 |
return false; |
return FALSE; |
1121 |
} |
} |
1122 |
|
|
1123 |
/* See if we should include an archive element. This version is used |
/* See if we should include an archive element. This version is used |
1125 |
the symbol name, presumably because we have some other mechanism |
the symbol name, presumably because we have some other mechanism |
1126 |
for finding them. */ |
for finding them. */ |
1127 |
|
|
1128 |
static boolean |
static bfd_boolean |
1129 |
generic_link_check_archive_element_no_collect (abfd, info, pneeded) |
generic_link_check_archive_element_no_collect ( |
1130 |
bfd *abfd; |
bfd *abfd, |
1131 |
struct bfd_link_info *info; |
struct bfd_link_info *info, |
1132 |
boolean *pneeded; |
bfd_boolean *pneeded) |
1133 |
{ |
{ |
1134 |
return generic_link_check_archive_element (abfd, info, pneeded, false); |
return generic_link_check_archive_element (abfd, info, pneeded, FALSE); |
1135 |
} |
} |
1136 |
|
|
1137 |
/* See if we should include an archive element. This version is used |
/* See if we should include an archive element. This version is used |
1138 |
when we want to automatically collect constructors based on the |
when we want to automatically collect constructors based on the |
1139 |
symbol name, as collect2 does. */ |
symbol name, as collect2 does. */ |
1140 |
|
|
1141 |
static boolean |
static bfd_boolean |
1142 |
generic_link_check_archive_element_collect (abfd, info, pneeded) |
generic_link_check_archive_element_collect (bfd *abfd, |
1143 |
bfd *abfd; |
struct bfd_link_info *info, |
1144 |
struct bfd_link_info *info; |
bfd_boolean *pneeded) |
|
boolean *pneeded; |
|
1145 |
{ |
{ |
1146 |
return generic_link_check_archive_element (abfd, info, pneeded, true); |
return generic_link_check_archive_element (abfd, info, pneeded, TRUE); |
1147 |
} |
} |
1148 |
|
|
1149 |
/* See if we should include an archive element. Optionally collect |
/* See if we should include an archive element. Optionally collect |
1150 |
constructors. */ |
constructors. */ |
1151 |
|
|
1152 |
static boolean |
static bfd_boolean |
1153 |
generic_link_check_archive_element (abfd, info, pneeded, collect) |
generic_link_check_archive_element (bfd *abfd, |
1154 |
bfd *abfd; |
struct bfd_link_info *info, |
1155 |
struct bfd_link_info *info; |
bfd_boolean *pneeded, |
1156 |
boolean *pneeded; |
bfd_boolean collect) |
|
boolean collect; |
|
1157 |
{ |
{ |
1158 |
asymbol **pp, **ppend; |
asymbol **pp, **ppend; |
1159 |
|
|
1160 |
*pneeded = false; |
*pneeded = FALSE; |
1161 |
|
|
1162 |
if (! generic_link_read_symbols (abfd)) |
if (! generic_link_read_symbols (abfd)) |
1163 |
return false; |
return FALSE; |
1164 |
|
|
1165 |
pp = _bfd_generic_link_get_symbols (abfd); |
pp = _bfd_generic_link_get_symbols (abfd); |
1166 |
ppend = pp + _bfd_generic_link_get_symcount (abfd); |
ppend = pp + _bfd_generic_link_get_symcount (abfd); |
1181 |
symbol (type bfd_link_hash_undefweak) is not considered to be |
symbol (type bfd_link_hash_undefweak) is not considered to be |
1182 |
a reference when pulling files out of an archive. See the |
a reference when pulling files out of an archive. See the |
1183 |
SVR4 ABI, p. 4-27. */ |
SVR4 ABI, p. 4-27. */ |
1184 |
h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false, |
h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), FALSE, |
1185 |
false, true); |
FALSE, TRUE); |
1186 |
if (h == (struct bfd_link_hash_entry *) NULL |
if (h == NULL |
1187 |
|| (h->type != bfd_link_hash_undefined |
|| (h->type != bfd_link_hash_undefined |
1188 |
&& h->type != bfd_link_hash_common)) |
&& h->type != bfd_link_hash_common)) |
1189 |
continue; |
continue; |
1198 |
/* This object file defines this symbol, so pull it in. */ |
/* This object file defines this symbol, so pull it in. */ |
1199 |
if (! (*info->callbacks->add_archive_element) (info, abfd, |
if (! (*info->callbacks->add_archive_element) (info, abfd, |
1200 |
bfd_asymbol_name (p))) |
bfd_asymbol_name (p))) |
1201 |
return false; |
return FALSE; |
1202 |
symcount = _bfd_generic_link_get_symcount (abfd); |
symcount = _bfd_generic_link_get_symcount (abfd); |
1203 |
symbols = _bfd_generic_link_get_symbols (abfd); |
symbols = _bfd_generic_link_get_symbols (abfd); |
1204 |
if (! generic_link_add_symbol_list (abfd, info, symcount, |
if (! generic_link_add_symbol_list (abfd, info, symcount, |
1205 |
symbols, collect)) |
symbols, collect)) |
1206 |
return false; |
return FALSE; |
1207 |
*pneeded = true; |
*pneeded = TRUE; |
1208 |
return true; |
return TRUE; |
1209 |
} |
} |
1210 |
|
|
1211 |
/* P is a common symbol. */ |
/* P is a common symbol. */ |
1217 |
unsigned int power; |
unsigned int power; |
1218 |
|
|
1219 |
symbfd = h->u.undef.abfd; |
symbfd = h->u.undef.abfd; |
1220 |
if (symbfd == (bfd *) NULL) |
if (symbfd == NULL) |
1221 |
{ |
{ |
1222 |
/* This symbol was created as undefined from outside |
/* This symbol was created as undefined from outside |
1223 |
BFD. We assume that we should link in the object |
BFD. We assume that we should link in the object |
1224 |
file. This is for the -u option in the linker. */ |
file. This is for the -u option in the linker. */ |
1225 |
if (! (*info->callbacks->add_archive_element) |
if (! (*info->callbacks->add_archive_element) |
1226 |
(info, abfd, bfd_asymbol_name (p))) |
(info, abfd, bfd_asymbol_name (p))) |
1227 |
return false; |
return FALSE; |
1228 |
*pneeded = true; |
*pneeded = TRUE; |
1229 |
return true; |
return TRUE; |
1230 |
} |
} |
1231 |
|
|
1232 |
/* Turn the symbol into a common symbol but do not link in |
/* Turn the symbol into a common symbol but do not link in |
1238 |
will be linked in. */ |
will be linked in. */ |
1239 |
h->type = bfd_link_hash_common; |
h->type = bfd_link_hash_common; |
1240 |
h->u.c.p = |
h->u.c.p = |
1241 |
((struct bfd_link_hash_common_entry *) |
bfd_hash_allocate (&info->hash->table, |
1242 |
bfd_hash_allocate (&info->hash->table, |
sizeof (struct bfd_link_hash_common_entry)); |
|
sizeof (struct bfd_link_hash_common_entry))); |
|
1243 |
if (h->u.c.p == NULL) |
if (h->u.c.p == NULL) |
1244 |
return false; |
return FALSE; |
1245 |
|
|
1246 |
size = bfd_asymbol_value (p); |
size = bfd_asymbol_value (p); |
1247 |
h->u.c.size = size; |
h->u.c.size = size; |
1270 |
} |
} |
1271 |
|
|
1272 |
/* This archive element is not needed. */ |
/* This archive element is not needed. */ |
1273 |
return true; |
return TRUE; |
1274 |
} |
} |
1275 |
|
|
1276 |
/* Add the symbols from an object file to the global hash table. ABFD |
/* Add the symbols from an object file to the global hash table. ABFD |
1277 |
is the object file. INFO is the linker information. SYMBOL_COUNT |
is the object file. INFO is the linker information. SYMBOL_COUNT |
1278 |
is the number of symbols. SYMBOLS is the list of symbols. COLLECT |
is the number of symbols. SYMBOLS is the list of symbols. COLLECT |
1279 |
is true if constructors should be automatically collected by name |
is TRUE if constructors should be automatically collected by name |
1280 |
as is done by collect2. */ |
as is done by collect2. */ |
1281 |
|
|
1282 |
static boolean |
static bfd_boolean |
1283 |
generic_link_add_symbol_list (abfd, info, symbol_count, symbols, collect) |
generic_link_add_symbol_list (bfd *abfd, |
1284 |
bfd *abfd; |
struct bfd_link_info *info, |
1285 |
struct bfd_link_info *info; |
bfd_size_type symbol_count, |
1286 |
bfd_size_type symbol_count; |
asymbol **symbols, |
1287 |
asymbol **symbols; |
bfd_boolean collect) |
|
boolean collect; |
|
1288 |
{ |
{ |
1289 |
asymbol **pp, **ppend; |
asymbol **pp, **ppend; |
1290 |
|
|
1308 |
const char *name; |
const char *name; |
1309 |
const char *string; |
const char *string; |
1310 |
struct generic_link_hash_entry *h; |
struct generic_link_hash_entry *h; |
1311 |
|
struct bfd_link_hash_entry *bh; |
1312 |
|
|
1313 |
name = bfd_asymbol_name (p); |
name = bfd_asymbol_name (p); |
1314 |
if (((p->flags & BSF_INDIRECT) != 0 |
if (((p->flags & BSF_INDIRECT) != 0 |
1330 |
else |
else |
1331 |
string = NULL; |
string = NULL; |
1332 |
|
|
1333 |
h = NULL; |
bh = NULL; |
1334 |
if (! (_bfd_generic_link_add_one_symbol |
if (! (_bfd_generic_link_add_one_symbol |
1335 |
(info, abfd, name, p->flags, bfd_get_section (p), |
(info, abfd, name, p->flags, bfd_get_section (p), |
1336 |
p->value, string, false, collect, |
p->value, string, FALSE, collect, &bh))) |
1337 |
(struct bfd_link_hash_entry **) &h))) |
return FALSE; |
1338 |
return false; |
h = (struct generic_link_hash_entry *) bh; |
1339 |
|
|
1340 |
/* If this is a constructor symbol, and the linker didn't do |
/* If this is a constructor symbol, and the linker didn't do |
1341 |
anything with it, then we want to just pass the symbol |
anything with it, then we want to just pass the symbol |
1358 |
generic one. */ |
generic one. */ |
1359 |
if (info->hash->creator == abfd->xvec) |
if (info->hash->creator == abfd->xvec) |
1360 |
{ |
{ |
1361 |
if (h->sym == (asymbol *) NULL |
if (h->sym == NULL |
1362 |
|| (! bfd_is_und_section (bfd_get_section (p)) |
|| (! bfd_is_und_section (bfd_get_section (p)) |
1363 |
&& (! bfd_is_com_section (bfd_get_section (p)) |
&& (! bfd_is_com_section (bfd_get_section (p)) |
1364 |
|| bfd_is_und_section (bfd_get_section (h->sym))))) |
|| bfd_is_und_section (bfd_get_section (h->sym))))) |
1377 |
it gets rewritten to not use asymbol structures. |
it gets rewritten to not use asymbol structures. |
1378 |
Setting this is also used to check whether these |
Setting this is also used to check whether these |
1379 |
symbols were set up by the generic linker. */ |
symbols were set up by the generic linker. */ |
1380 |
p->udata.p = (PTR) h; |
p->udata.p = h; |
1381 |
} |
} |
1382 |
} |
} |
1383 |
|
|
1384 |
return true; |
return TRUE; |
1385 |
} |
} |
1386 |
|
|
1387 |
/* We use a state table to deal with adding symbols from an object |
/* We use a state table to deal with adding symbols from an object |
1477 |
/* Return the BFD in which a hash entry has been defined, if known. */ |
/* Return the BFD in which a hash entry has been defined, if known. */ |
1478 |
|
|
1479 |
static bfd * |
static bfd * |
1480 |
hash_entry_bfd (h) |
hash_entry_bfd (struct bfd_link_hash_entry *h) |
|
struct bfd_link_hash_entry *h; |
|
1481 |
{ |
{ |
1482 |
while (h->type == bfd_link_hash_warning) |
while (h->type == bfd_link_hash_warning) |
1483 |
h = h->u.i.link; |
h = h->u.i.link; |
1507 |
STRING is used for either an indirect symbol, in which case it is |
STRING is used for either an indirect symbol, in which case it is |
1508 |
the name of the symbol to indirect to, or a warning symbol, in |
the name of the symbol to indirect to, or a warning symbol, in |
1509 |
which case it is the warning string. |
which case it is the warning string. |
1510 |
COPY is true if NAME or STRING must be copied into locally |
COPY is TRUE if NAME or STRING must be copied into locally |
1511 |
allocated memory if they need to be saved. |
allocated memory if they need to be saved. |
1512 |
COLLECT is true if we should automatically collect gcc constructor |
COLLECT is TRUE if we should automatically collect gcc constructor |
1513 |
or destructor names as collect2 does. |
or destructor names as collect2 does. |
1514 |
HASHP, if not NULL, is a place to store the created hash table |
HASHP, if not NULL, is a place to store the created hash table |
1515 |
entry; if *HASHP is not NULL, the caller has already looked up |
entry; if *HASHP is not NULL, the caller has already looked up |
1516 |
the hash table entry, and stored it in *HASHP. */ |
the hash table entry, and stored it in *HASHP. */ |
1517 |
|
|
1518 |
boolean |
bfd_boolean |
1519 |
_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, |
_bfd_generic_link_add_one_symbol (struct bfd_link_info *info, |
1520 |
string, copy, collect, hashp) |
bfd *abfd, |
1521 |
struct bfd_link_info *info; |
const char *name, |
1522 |
bfd *abfd; |
flagword flags, |
1523 |
const char *name; |
asection *section, |
1524 |
flagword flags; |
bfd_vma value, |
1525 |
asection *section; |
const char *string, |
1526 |
bfd_vma value; |
bfd_boolean copy, |
1527 |
const char *string; |
bfd_boolean collect, |
1528 |
boolean copy; |
struct bfd_link_hash_entry **hashp) |
|
boolean collect; |
|
|
struct bfd_link_hash_entry **hashp; |
|
1529 |
{ |
{ |
1530 |
enum link_row row; |
enum link_row row; |
1531 |
struct bfd_link_hash_entry *h; |
struct bfd_link_hash_entry *h; |
1532 |
boolean cycle; |
bfd_boolean cycle; |
1533 |
|
|
1534 |
if (bfd_is_ind_section (section) |
if (bfd_is_ind_section (section) |
1535 |
|| (flags & BSF_INDIRECT) != 0) |
|| (flags & BSF_INDIRECT) != 0) |
1557 |
else |
else |
1558 |
{ |
{ |
1559 |
if (row == UNDEF_ROW || row == UNDEFW_ROW) |
if (row == UNDEF_ROW || row == UNDEFW_ROW) |
1560 |
h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false); |
h = bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE); |
1561 |
else |
else |
1562 |
h = bfd_link_hash_lookup (info->hash, name, true, copy, false); |
h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE); |
1563 |
if (h == NULL) |
if (h == NULL) |
1564 |
{ |
{ |
1565 |
if (hashp != NULL) |
if (hashp != NULL) |
1566 |
*hashp = NULL; |
*hashp = NULL; |
1567 |
return false; |
return FALSE; |
1568 |
} |
} |
1569 |
} |
} |
1570 |
|
|
1571 |
if (info->notice_all |
if (info->notice_all |
1572 |
|| (info->notice_hash != (struct bfd_hash_table *) NULL |
|| (info->notice_hash != NULL |
1573 |
&& (bfd_hash_lookup (info->notice_hash, name, false, false) |
&& bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)) |
|
!= (struct bfd_hash_entry *) NULL))) |
|
1574 |
{ |
{ |
1575 |
if (! (*info->callbacks->notice) (info, h->root.string, abfd, section, |
if (! (*info->callbacks->notice) (info, h->root.string, abfd, section, |
1576 |
value)) |
value)) |
1577 |
return false; |
return FALSE; |
1578 |
} |
} |
1579 |
|
|
1580 |
if (hashp != (struct bfd_link_hash_entry **) NULL) |
if (hashp != NULL) |
1581 |
*hashp = h; |
*hashp = h; |
1582 |
|
|
1583 |
do |
do |
1584 |
{ |
{ |
1585 |
enum link_action action; |
enum link_action action; |
1586 |
|
|
1587 |
cycle = false; |
cycle = FALSE; |
1588 |
action = link_action[(int) row][(int) h->type]; |
action = link_action[(int) row][(int) h->type]; |
1589 |
switch (action) |
switch (action) |
1590 |
{ |
{ |
1606 |
/* Make a new weak undefined symbol. */ |
/* Make a new weak undefined symbol. */ |
1607 |
h->type = bfd_link_hash_undefweak; |
h->type = bfd_link_hash_undefweak; |
1608 |
h->u.undef.abfd = abfd; |
h->u.undef.abfd = abfd; |
1609 |
|
h->u.undef.weak = abfd; |
1610 |
break; |
break; |
1611 |
|
|
1612 |
case CDEF: |
case CDEF: |
1616 |
if (! ((*info->callbacks->multiple_common) |
if (! ((*info->callbacks->multiple_common) |
1617 |
(info, h->root.string, |
(info, h->root.string, |
1618 |
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, |
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, |
1619 |
abfd, bfd_link_hash_defined, (bfd_vma) 0))) |
abfd, bfd_link_hash_defined, 0))) |
1620 |
return false; |
return FALSE; |
1621 |
/* Fall through. */ |
/* Fall through. */ |
1622 |
case DEF: |
case DEF: |
1623 |
case DEFW: |
case DEFW: |
1677 |
if (! ((*info->callbacks->constructor) |
if (! ((*info->callbacks->constructor) |
1678 |
(info, c == 'I', |
(info, c == 'I', |
1679 |
h->root.string, abfd, section, value))) |
h->root.string, abfd, section, value))) |
1680 |
return false; |
return FALSE; |
1681 |
} |
} |
1682 |
} |
} |
1683 |
} |
} |
1691 |
bfd_link_add_undef (info->hash, h); |
bfd_link_add_undef (info->hash, h); |
1692 |
h->type = bfd_link_hash_common; |
h->type = bfd_link_hash_common; |
1693 |
h->u.c.p = |
h->u.c.p = |
1694 |
((struct bfd_link_hash_common_entry *) |
bfd_hash_allocate (&info->hash->table, |
1695 |
bfd_hash_allocate (&info->hash->table, |
sizeof (struct bfd_link_hash_common_entry)); |
|
sizeof (struct bfd_link_hash_common_entry))); |
|
1696 |
if (h->u.c.p == NULL) |
if (h->u.c.p == NULL) |
1697 |
return false; |
return FALSE; |
1698 |
|
|
1699 |
h->u.c.size = value; |
h->u.c.size = value; |
1700 |
|
|
1736 |
|
|
1737 |
case REF: |
case REF: |
1738 |
/* A reference to a defined symbol. */ |
/* A reference to a defined symbol. */ |
1739 |
if (h->next == NULL && info->hash->undefs_tail != h) |
if (h->u.undef.next == NULL && info->hash->undefs_tail != h) |
1740 |
h->next = h; |
h->u.undef.next = h; |
1741 |
break; |
break; |
1742 |
|
|
1743 |
case BIG: |
case BIG: |
1749 |
(info, h->root.string, |
(info, h->root.string, |
1750 |
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, |
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, |
1751 |
abfd, bfd_link_hash_common, value))) |
abfd, bfd_link_hash_common, value))) |
1752 |
return false; |
return FALSE; |
1753 |
if (value > h->u.c.size) |
if (value > h->u.c.size) |
1754 |
{ |
{ |
1755 |
unsigned int power; |
unsigned int power; |
1798 |
else |
else |
1799 |
obfd = NULL; |
obfd = NULL; |
1800 |
if (! ((*info->callbacks->multiple_common) |
if (! ((*info->callbacks->multiple_common) |
1801 |
(info, h->root.string, obfd, h->type, (bfd_vma) 0, |
(info, h->root.string, obfd, h->type, 0, |
1802 |
abfd, bfd_link_hash_common, value))) |
abfd, bfd_link_hash_common, value))) |
1803 |
return false; |
return FALSE; |
1804 |
} |
} |
1805 |
break; |
break; |
1806 |
|
|
1842 |
if (! ((*info->callbacks->multiple_definition) |
if (! ((*info->callbacks->multiple_definition) |
1843 |
(info, h->root.string, msec->owner, msec, mval, |
(info, h->root.string, msec->owner, msec, mval, |
1844 |
abfd, section, value))) |
abfd, section, value))) |
1845 |
return false; |
return FALSE; |
1846 |
} |
} |
1847 |
break; |
break; |
1848 |
|
|
1852 |
if (! ((*info->callbacks->multiple_common) |
if (! ((*info->callbacks->multiple_common) |
1853 |
(info, h->root.string, |
(info, h->root.string, |
1854 |
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, |
h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size, |
1855 |
abfd, bfd_link_hash_indirect, (bfd_vma) 0))) |
abfd, bfd_link_hash_indirect, 0))) |
1856 |
return false; |
return FALSE; |
1857 |
/* Fall through. */ |
/* Fall through. */ |
1858 |
case IND: |
case IND: |
1859 |
/* Create an indirect symbol. */ |
/* Create an indirect symbol. */ |
1862 |
|
|
1863 |
/* STRING is the name of the symbol we want to indirect |
/* STRING is the name of the symbol we want to indirect |
1864 |
to. */ |
to. */ |
1865 |
inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true, |
inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE, |
1866 |
copy, false); |
copy, FALSE); |
1867 |
if (inh == (struct bfd_link_hash_entry *) NULL) |
if (inh == NULL) |
1868 |
return false; |
return FALSE; |
1869 |
if (inh->type == bfd_link_hash_indirect |
if (inh->type == bfd_link_hash_indirect |
1870 |
&& inh->u.i.link == h) |
&& inh->u.i.link == h) |
1871 |
{ |
{ |
1872 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1873 |
(_("%s: indirect symbol `%s' to `%s' is a loop"), |
(_("%B: indirect symbol `%s' to `%s' is a loop"), |
1874 |
bfd_archive_filename (abfd), name, string); |
abfd, name, string); |
1875 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
1876 |
return false; |
return FALSE; |
1877 |
} |
} |
1878 |
if (inh->type == bfd_link_hash_new) |
if (inh->type == bfd_link_hash_new) |
1879 |
{ |
{ |
1888 |
if (h->type != bfd_link_hash_new) |
if (h->type != bfd_link_hash_new) |
1889 |
{ |
{ |
1890 |
row = UNDEF_ROW; |
row = UNDEF_ROW; |
1891 |
cycle = true; |
cycle = TRUE; |
1892 |
} |
} |
1893 |
|
|
1894 |
h->type = bfd_link_hash_indirect; |
h->type = bfd_link_hash_indirect; |
1900 |
/* Add an entry to a set. */ |
/* Add an entry to a set. */ |
1901 |
if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR, |
if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR, |
1902 |
abfd, section, value)) |
abfd, section, value)) |
1903 |
return false; |
return FALSE; |
1904 |
break; |
break; |
1905 |
|
|
1906 |
case WARNC: |
case WARNC: |
1909 |
{ |
{ |
1910 |
if (! (*info->callbacks->warning) (info, h->u.i.warning, |
if (! (*info->callbacks->warning) (info, h->u.i.warning, |
1911 |
h->root.string, abfd, |
h->root.string, abfd, |
1912 |
(asection *) NULL, |
NULL, 0)) |
1913 |
(bfd_vma) 0)) |
return FALSE; |
|
return false; |
|
1914 |
/* Only issue a warning once. */ |
/* Only issue a warning once. */ |
1915 |
h->u.i.warning = NULL; |
h->u.i.warning = NULL; |
1916 |
} |
} |
1918 |
case CYCLE: |
case CYCLE: |
1919 |
/* Try again with the referenced symbol. */ |
/* Try again with the referenced symbol. */ |
1920 |
h = h->u.i.link; |
h = h->u.i.link; |
1921 |
cycle = true; |
cycle = TRUE; |
1922 |
break; |
break; |
1923 |
|
|
1924 |
case REFC: |
case REFC: |
1925 |
/* A reference to an indirect symbol. */ |
/* A reference to an indirect symbol. */ |
1926 |
if (h->next == NULL && info->hash->undefs_tail != h) |
if (h->u.undef.next == NULL && info->hash->undefs_tail != h) |
1927 |
h->next = h; |
h->u.undef.next = h; |
1928 |
h = h->u.i.link; |
h = h->u.i.link; |
1929 |
cycle = true; |
cycle = TRUE; |
1930 |
break; |
break; |
1931 |
|
|
1932 |
case WARN: |
case WARN: |
1933 |
/* Issue a warning. */ |
/* Issue a warning. */ |
1934 |
if (! (*info->callbacks->warning) (info, string, h->root.string, |
if (! (*info->callbacks->warning) (info, string, h->root.string, |
1935 |
hash_entry_bfd (h), |
hash_entry_bfd (h), NULL, 0)) |
1936 |
(asection *) NULL, (bfd_vma) 0)) |
return FALSE; |
|
return false; |
|
1937 |
break; |
break; |
1938 |
|
|
1939 |
case CWARN: |
case CWARN: |
1940 |
/* Warn if this symbol has been referenced already, |
/* Warn if this symbol has been referenced already, |
1941 |
otherwise add a warning. A symbol has been referenced if |
otherwise add a warning. A symbol has been referenced if |
1942 |
the next field is not NULL, or it is the tail of the |
the u.undef.next field is not NULL, or it is the tail of the |
1943 |
undefined symbol list. The REF case above helps to |
undefined symbol list. The REF case above helps to |
1944 |
ensure this. */ |
ensure this. */ |
1945 |
if (h->next != NULL || info->hash->undefs_tail == h) |
if (h->u.undef.next != NULL || info->hash->undefs_tail == h) |
1946 |
{ |
{ |
1947 |
if (! (*info->callbacks->warning) (info, string, h->root.string, |
if (! (*info->callbacks->warning) (info, string, h->root.string, |
1948 |
hash_entry_bfd (h), |
hash_entry_bfd (h), NULL, 0)) |
1949 |
(asection *) NULL, |
return FALSE; |
|
(bfd_vma) 0)) |
|
|
return false; |
|
1950 |
break; |
break; |
1951 |
} |
} |
1952 |
/* Fall through. */ |
/* Fall through. */ |
1958 |
/* STRING is the warning to give. */ |
/* STRING is the warning to give. */ |
1959 |
sub = ((struct bfd_link_hash_entry *) |
sub = ((struct bfd_link_hash_entry *) |
1960 |
((*info->hash->table.newfunc) |
((*info->hash->table.newfunc) |
1961 |
((struct bfd_hash_entry *) NULL, &info->hash->table, |
(NULL, &info->hash->table, h->root.string))); |
|
h->root.string))); |
|
1962 |
if (sub == NULL) |
if (sub == NULL) |
1963 |
return false; |
return FALSE; |
1964 |
*sub = *h; |
*sub = *h; |
1965 |
sub->type = bfd_link_hash_warning; |
sub->type = bfd_link_hash_warning; |
1966 |
sub->u.i.link = h; |
sub->u.i.link = h; |
1973 |
|
|
1974 |
w = bfd_hash_allocate (&info->hash->table, len); |
w = bfd_hash_allocate (&info->hash->table, len); |
1975 |
if (w == NULL) |
if (w == NULL) |
1976 |
return false; |
return FALSE; |
1977 |
memcpy (w, string, len); |
memcpy (w, string, len); |
1978 |
sub->u.i.warning = w; |
sub->u.i.warning = w; |
1979 |
} |
} |
1989 |
} |
} |
1990 |
while (cycle); |
while (cycle); |
1991 |
|
|
1992 |
return true; |
return TRUE; |
1993 |
} |
} |
1994 |
|
|
1995 |
/* Generic final link routine. */ |
/* Generic final link routine. */ |
1996 |
|
|
1997 |
boolean |
bfd_boolean |
1998 |
_bfd_generic_final_link (abfd, info) |
_bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
1999 |
{ |
{ |
2000 |
bfd *sub; |
bfd *sub; |
2001 |
asection *o; |
asection *o; |
2003 |
size_t outsymalloc; |
size_t outsymalloc; |
2004 |
struct generic_write_global_symbol_info wginfo; |
struct generic_write_global_symbol_info wginfo; |
2005 |
|
|
2006 |
bfd_get_outsymbols (abfd) = (asymbol **) NULL; |
bfd_get_outsymbols (abfd) = NULL; |
2007 |
bfd_get_symcount (abfd) = 0; |
bfd_get_symcount (abfd) = 0; |
2008 |
outsymalloc = 0; |
outsymalloc = 0; |
2009 |
|
|
2011 |
for (o = abfd->sections; o != NULL; o = o->next) |
for (o = abfd->sections; o != NULL; o = o->next) |
2012 |
for (p = o->link_order_head; p != NULL; p = p->next) |
for (p = o->link_order_head; p != NULL; p = p->next) |
2013 |
if (p->type == bfd_indirect_link_order) |
if (p->type == bfd_indirect_link_order) |
2014 |
p->u.indirect.section->linker_mark = true; |
p->u.indirect.section->linker_mark = TRUE; |
2015 |
|
|
2016 |
/* Build the output symbol table. */ |
/* Build the output symbol table. */ |
2017 |
for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next) |
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) |
2018 |
if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc)) |
if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc)) |
2019 |
return false; |
return FALSE; |
2020 |
|
|
2021 |
/* Accumulate the global symbols. */ |
/* Accumulate the global symbols. */ |
2022 |
wginfo.info = info; |
wginfo.info = info; |
2024 |
wginfo.psymalloc = &outsymalloc; |
wginfo.psymalloc = &outsymalloc; |
2025 |
_bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info), |
_bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info), |
2026 |
_bfd_generic_link_write_global_symbol, |
_bfd_generic_link_write_global_symbol, |
2027 |
(PTR) &wginfo); |
&wginfo); |
2028 |
|
|
2029 |
/* Make sure we have a trailing NULL pointer on OUTSYMBOLS. We |
/* Make sure we have a trailing NULL pointer on OUTSYMBOLS. We |
2030 |
shouldn't really need one, since we have SYMCOUNT, but some old |
shouldn't really need one, since we have SYMCOUNT, but some old |
2031 |
code still expects one. */ |
code still expects one. */ |
2032 |
if (! generic_add_output_symbol (abfd, &outsymalloc, NULL)) |
if (! generic_add_output_symbol (abfd, &outsymalloc, NULL)) |
2033 |
return false; |
return FALSE; |
2034 |
|
|
2035 |
if (info->relocateable) |
if (info->relocatable) |
2036 |
{ |
{ |
2037 |
/* Allocate space for the output relocs for each section. */ |
/* Allocate space for the output relocs for each section. */ |
2038 |
for (o = abfd->sections; |
for (o = abfd->sections; o != NULL; o = o->next) |
|
o != (asection *) NULL; |
|
|
o = o->next) |
|
2039 |
{ |
{ |
2040 |
o->reloc_count = 0; |
o->reloc_count = 0; |
2041 |
for (p = o->link_order_head; |
for (p = o->link_order_head; p != NULL; p = p->next) |
|
p != (struct bfd_link_order *) NULL; |
|
|
p = p->next) |
|
2042 |
{ |
{ |
2043 |
if (p->type == bfd_section_reloc_link_order |
if (p->type == bfd_section_reloc_link_order |
2044 |
|| p->type == bfd_symbol_reloc_link_order) |
|| p->type == bfd_symbol_reloc_link_order) |
2057 |
relsize = bfd_get_reloc_upper_bound (input_bfd, |
relsize = bfd_get_reloc_upper_bound (input_bfd, |
2058 |
input_section); |
input_section); |
2059 |
if (relsize < 0) |
if (relsize < 0) |
2060 |
return false; |
return FALSE; |
2061 |
relocs = (arelent **) bfd_malloc ((bfd_size_type) relsize); |
relocs = bfd_malloc (relsize); |
2062 |
if (!relocs && relsize != 0) |
if (!relocs && relsize != 0) |
2063 |
return false; |
return FALSE; |
2064 |
symbols = _bfd_generic_link_get_symbols (input_bfd); |
symbols = _bfd_generic_link_get_symbols (input_bfd); |
2065 |
reloc_count = bfd_canonicalize_reloc (input_bfd, |
reloc_count = bfd_canonicalize_reloc (input_bfd, |
2066 |
input_section, |
input_section, |
2067 |
relocs, |
relocs, |
2068 |
symbols); |
symbols); |
2069 |
|
free (relocs); |
2070 |
if (reloc_count < 0) |
if (reloc_count < 0) |
2071 |
return false; |
return FALSE; |
2072 |
BFD_ASSERT ((unsigned long) reloc_count |
BFD_ASSERT ((unsigned long) reloc_count |
2073 |
== input_section->reloc_count); |
== input_section->reloc_count); |
2074 |
o->reloc_count += reloc_count; |
o->reloc_count += reloc_count; |
|
free (relocs); |
|
2075 |
} |
} |
2076 |
} |
} |
2077 |
if (o->reloc_count > 0) |
if (o->reloc_count > 0) |
2080 |
|
|
2081 |
amt = o->reloc_count; |
amt = o->reloc_count; |
2082 |
amt *= sizeof (arelent *); |
amt *= sizeof (arelent *); |
2083 |
o->orelocation = (arelent **) bfd_alloc (abfd, amt); |
o->orelocation = bfd_alloc (abfd, amt); |
2084 |
if (!o->orelocation) |
if (!o->orelocation) |
2085 |
return false; |
return FALSE; |
2086 |
o->flags |= SEC_RELOC; |
o->flags |= SEC_RELOC; |
2087 |
/* Reset the count so that it can be used as an index |
/* Reset the count so that it can be used as an index |
2088 |
when putting in the output relocs. */ |
when putting in the output relocs. */ |
2092 |
} |
} |
2093 |
|
|
2094 |
/* Handle all the link order information for the sections. */ |
/* Handle all the link order information for the sections. */ |
2095 |
for (o = abfd->sections; |
for (o = abfd->sections; o != NULL; o = o->next) |
2096 |
o != (asection *) NULL; |
{ |
2097 |
o = o->next) |
for (p = o->link_order_head; p != NULL; p = p->next) |
|
{ |
|
|
for (p = o->link_order_head; |
|
|
p != (struct bfd_link_order *) NULL; |
|
|
p = p->next) |
|
2098 |
{ |
{ |
2099 |
switch (p->type) |
switch (p->type) |
2100 |
{ |
{ |
2101 |
case bfd_section_reloc_link_order: |
case bfd_section_reloc_link_order: |
2102 |
case bfd_symbol_reloc_link_order: |
case bfd_symbol_reloc_link_order: |
2103 |
if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) |
if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) |
2104 |
return false; |
return FALSE; |
2105 |
break; |
break; |
2106 |
case bfd_indirect_link_order: |
case bfd_indirect_link_order: |
2107 |
if (! default_indirect_link_order (abfd, info, o, p, true)) |
if (! default_indirect_link_order (abfd, info, o, p, TRUE)) |
2108 |
return false; |
return FALSE; |
2109 |
break; |
break; |
2110 |
default: |
default: |
2111 |
if (! _bfd_default_link_order (abfd, info, o, p)) |
if (! _bfd_default_link_order (abfd, info, o, p)) |
2112 |
return false; |
return FALSE; |
2113 |
break; |
break; |
2114 |
} |
} |
2115 |
} |
} |
2116 |
} |
} |
2117 |
|
|
2118 |
return true; |
return TRUE; |
2119 |
} |
} |
2120 |
|
|
2121 |
/* Add an output symbol to the output BFD. */ |
/* Add an output symbol to the output BFD. */ |
2122 |
|
|
2123 |
static boolean |
static bfd_boolean |
2124 |
generic_add_output_symbol (output_bfd, psymalloc, sym) |
generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym) |
|
bfd *output_bfd; |
|
|
size_t *psymalloc; |
|
|
asymbol *sym; |
|
2125 |
{ |
{ |
2126 |
if (bfd_get_symcount (output_bfd) >= *psymalloc) |
if (bfd_get_symcount (output_bfd) >= *psymalloc) |
2127 |
{ |
{ |
2134 |
*psymalloc *= 2; |
*psymalloc *= 2; |
2135 |
amt = *psymalloc; |
amt = *psymalloc; |
2136 |
amt *= sizeof (asymbol *); |
amt *= sizeof (asymbol *); |
2137 |
newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt); |
newsyms = bfd_realloc (bfd_get_outsymbols (output_bfd), amt); |
2138 |
if (newsyms == (asymbol **) NULL) |
if (newsyms == NULL) |
2139 |
return false; |
return FALSE; |
2140 |
bfd_get_outsymbols (output_bfd) = newsyms; |
bfd_get_outsymbols (output_bfd) = newsyms; |
2141 |
} |
} |
2142 |
|
|
2144 |
if (sym != NULL) |
if (sym != NULL) |
2145 |
++ bfd_get_symcount (output_bfd); |
++ bfd_get_symcount (output_bfd); |
2146 |
|
|
2147 |
return true; |
return TRUE; |
2148 |
} |
} |
2149 |
|
|
2150 |
/* Handle the symbols for an input BFD. */ |
/* Handle the symbols for an input BFD. */ |
2151 |
|
|
2152 |
boolean |
bfd_boolean |
2153 |
_bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc) |
_bfd_generic_link_output_symbols (bfd *output_bfd, |
2154 |
bfd *output_bfd; |
bfd *input_bfd, |
2155 |
bfd *input_bfd; |
struct bfd_link_info *info, |
2156 |
struct bfd_link_info *info; |
size_t *psymalloc) |
|
size_t *psymalloc; |
|
2157 |
{ |
{ |
2158 |
asymbol **sym_ptr; |
asymbol **sym_ptr; |
2159 |
asymbol **sym_end; |
asymbol **sym_end; |
2160 |
|
|
2161 |
if (! generic_link_read_symbols (input_bfd)) |
if (! generic_link_read_symbols (input_bfd)) |
2162 |
return false; |
return FALSE; |
2163 |
|
|
2164 |
/* Create a filename symbol if we are supposed to. */ |
/* Create a filename symbol if we are supposed to. */ |
2165 |
if (info->create_object_symbols_section != (asection *) NULL) |
if (info->create_object_symbols_section != NULL) |
2166 |
{ |
{ |
2167 |
asection *sec; |
asection *sec; |
2168 |
|
|
2169 |
for (sec = input_bfd->sections; |
for (sec = input_bfd->sections; sec != NULL; sec = sec->next) |
|
sec != (asection *) NULL; |
|
|
sec = sec->next) |
|
2170 |
{ |
{ |
2171 |
if (sec->output_section == info->create_object_symbols_section) |
if (sec->output_section == info->create_object_symbols_section) |
2172 |
{ |
{ |
2174 |
|
|
2175 |
newsym = bfd_make_empty_symbol (input_bfd); |
newsym = bfd_make_empty_symbol (input_bfd); |
2176 |
if (!newsym) |
if (!newsym) |
2177 |
return false; |
return FALSE; |
2178 |
newsym->name = input_bfd->filename; |
newsym->name = input_bfd->filename; |
2179 |
newsym->value = 0; |
newsym->value = 0; |
2180 |
newsym->flags = BSF_LOCAL | BSF_FILE; |
newsym->flags = BSF_LOCAL | BSF_FILE; |
2182 |
|
|
2183 |
if (! generic_add_output_symbol (output_bfd, psymalloc, |
if (! generic_add_output_symbol (output_bfd, psymalloc, |
2184 |
newsym)) |
newsym)) |
2185 |
return false; |
return FALSE; |
2186 |
|
|
2187 |
break; |
break; |
2188 |
} |
} |
2197 |
{ |
{ |
2198 |
asymbol *sym; |
asymbol *sym; |
2199 |
struct generic_link_hash_entry *h; |
struct generic_link_hash_entry *h; |
2200 |
boolean output; |
bfd_boolean output; |
2201 |
|
|
2202 |
h = (struct generic_link_hash_entry *) NULL; |
h = NULL; |
2203 |
sym = *sym_ptr; |
sym = *sym_ptr; |
2204 |
if ((sym->flags & (BSF_INDIRECT |
if ((sym->flags & (BSF_INDIRECT |
2205 |
| BSF_WARNING |
| BSF_WARNING |
2211 |
|| bfd_is_ind_section (bfd_get_section (sym))) |
|| bfd_is_ind_section (bfd_get_section (sym))) |
2212 |
{ |
{ |
2213 |
if (sym->udata.p != NULL) |
if (sym->udata.p != NULL) |
2214 |
h = (struct generic_link_hash_entry *) sym->udata.p; |
h = sym->udata.p; |
2215 |
else if ((sym->flags & BSF_CONSTRUCTOR) != 0) |
else if ((sym->flags & BSF_CONSTRUCTOR) != 0) |
2216 |
{ |
{ |
2217 |
/* This case normally means that the main linker code |
/* This case normally means that the main linker code |
2228 |
h = ((struct generic_link_hash_entry *) |
h = ((struct generic_link_hash_entry *) |
2229 |
bfd_wrapped_link_hash_lookup (output_bfd, info, |
bfd_wrapped_link_hash_lookup (output_bfd, info, |
2230 |
bfd_asymbol_name (sym), |
bfd_asymbol_name (sym), |
2231 |
false, false, true)); |
FALSE, FALSE, TRUE)); |
2232 |
else |
else |
2233 |
h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), |
h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), |
2234 |
bfd_asymbol_name (sym), |
bfd_asymbol_name (sym), |
2235 |
false, false, true); |
FALSE, FALSE, TRUE); |
2236 |
|
|
2237 |
if (h != (struct generic_link_hash_entry *) NULL) |
if (h != NULL) |
2238 |
{ |
{ |
2239 |
/* Force all references to this symbol to point to |
/* Force all references to this symbol to point to |
2240 |
the same area in memory. It is possible that |
the same area in memory. It is possible that |
2243 |
check that. */ |
check that. */ |
2244 |
if (info->hash->creator == input_bfd->xvec) |
if (info->hash->creator == input_bfd->xvec) |
2245 |
{ |
{ |
2246 |
if (h->sym != (asymbol *) NULL) |
if (h->sym != NULL) |
2247 |
*sym_ptr = sym = h->sym; |
*sym_ptr = sym = h->sym; |
2248 |
} |
} |
2249 |
|
|
2295 |
write_file_locals in ldsym.c. */ |
write_file_locals in ldsym.c. */ |
2296 |
if (info->strip == strip_all |
if (info->strip == strip_all |
2297 |
|| (info->strip == strip_some |
|| (info->strip == strip_some |
2298 |
&& (bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), |
&& bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), |
2299 |
false, false) |
FALSE, FALSE) == NULL)) |
2300 |
== (struct bfd_hash_entry *) NULL))) |
output = FALSE; |
|
output = false; |
|
2301 |
else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0) |
else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0) |
2302 |
{ |
{ |
2303 |
/* If this symbol is marked as occurring now, rather |
/* If this symbol is marked as occurring now, rather |
2306 |
better way. */ |
better way. */ |
2307 |
if (bfd_asymbol_bfd (sym) == input_bfd |
if (bfd_asymbol_bfd (sym) == input_bfd |
2308 |
&& (sym->flags & BSF_NOT_AT_END) != 0) |
&& (sym->flags & BSF_NOT_AT_END) != 0) |
2309 |
output = true; |
output = TRUE; |
2310 |
else |
else |
2311 |
output = false; |
output = FALSE; |
2312 |
} |
} |
2313 |
else if (bfd_is_ind_section (sym->section)) |
else if (bfd_is_ind_section (sym->section)) |
2314 |
output = false; |
output = FALSE; |
2315 |
else if ((sym->flags & BSF_DEBUGGING) != 0) |
else if ((sym->flags & BSF_DEBUGGING) != 0) |
2316 |
{ |
{ |
2317 |
if (info->strip == strip_none) |
if (info->strip == strip_none) |
2318 |
output = true; |
output = TRUE; |
2319 |
else |
else |
2320 |
output = false; |
output = FALSE; |
2321 |
} |
} |
2322 |
else if (bfd_is_und_section (sym->section) |
else if (bfd_is_und_section (sym->section) |
2323 |
|| bfd_is_com_section (sym->section)) |
|| bfd_is_com_section (sym->section)) |
2324 |
output = false; |
output = FALSE; |
2325 |
else if ((sym->flags & BSF_LOCAL) != 0) |
else if ((sym->flags & BSF_LOCAL) != 0) |
2326 |
{ |
{ |
2327 |
if ((sym->flags & BSF_WARNING) != 0) |
if ((sym->flags & BSF_WARNING) != 0) |
2328 |
output = false; |
output = FALSE; |
2329 |
else |
else |
2330 |
{ |
{ |
2331 |
switch (info->discard) |
switch (info->discard) |
2332 |
{ |
{ |
2333 |
default: |
default: |
2334 |
case discard_all: |
case discard_all: |
2335 |
output = false; |
output = FALSE; |
2336 |
break; |
break; |
2337 |
case discard_sec_merge: |
case discard_sec_merge: |
2338 |
output = true; |
output = TRUE; |
2339 |
if (info->relocateable |
if (info->relocatable |
2340 |
|| ! (sym->section->flags & SEC_MERGE)) |
|| ! (sym->section->flags & SEC_MERGE)) |
2341 |
break; |
break; |
2342 |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
2343 |
case discard_l: |
case discard_l: |
2344 |
if (bfd_is_local_label (input_bfd, sym)) |
if (bfd_is_local_label (input_bfd, sym)) |
2345 |
output = false; |
output = FALSE; |
2346 |
else |
else |
2347 |
output = true; |
output = TRUE; |
2348 |
break; |
break; |
2349 |
case discard_none: |
case discard_none: |
2350 |
output = true; |
output = TRUE; |
2351 |
break; |
break; |
2352 |
} |
} |
2353 |
} |
} |
2355 |
else if ((sym->flags & BSF_CONSTRUCTOR)) |
else if ((sym->flags & BSF_CONSTRUCTOR)) |
2356 |
{ |
{ |
2357 |
if (info->strip != strip_all) |
if (info->strip != strip_all) |
2358 |
output = true; |
output = TRUE; |
2359 |
else |
else |
2360 |
output = false; |
output = FALSE; |
2361 |
} |
} |
2362 |
else |
else |
2363 |
abort (); |
abort (); |
2369 |
field set. */ |
field set. */ |
2370 |
if ((sym->section->flags & SEC_HAS_CONTENTS) != 0 |
if ((sym->section->flags & SEC_HAS_CONTENTS) != 0 |
2371 |
&& ! sym->section->linker_mark) |
&& ! sym->section->linker_mark) |
2372 |
output = false; |
output = FALSE; |
2373 |
|
|
2374 |
if (output) |
if (output) |
2375 |
{ |
{ |
2376 |
if (! generic_add_output_symbol (output_bfd, psymalloc, sym)) |
if (! generic_add_output_symbol (output_bfd, psymalloc, sym)) |
2377 |
return false; |
return FALSE; |
2378 |
if (h != (struct generic_link_hash_entry *) NULL) |
if (h != NULL) |
2379 |
h->written = true; |
h->written = TRUE; |
2380 |
} |
} |
2381 |
} |
} |
2382 |
|
|
2383 |
return true; |
return TRUE; |
2384 |
} |
} |
2385 |
|
|
2386 |
/* Set the section and value of a generic BFD symbol based on a linker |
/* Set the section and value of a generic BFD symbol based on a linker |
2387 |
hash table entry. */ |
hash table entry. */ |
2388 |
|
|
2389 |
static void |
static void |
2390 |
set_symbol_from_hash (sym, h) |
set_symbol_from_hash (asymbol *sym, struct bfd_link_hash_entry *h) |
|
asymbol *sym; |
|
|
struct bfd_link_hash_entry *h; |
|
2391 |
{ |
{ |
2392 |
switch (h->type) |
switch (h->type) |
2393 |
{ |
{ |
2447 |
/* Write out a global symbol, if it hasn't already been written out. |
/* Write out a global symbol, if it hasn't already been written out. |
2448 |
This is called for each symbol in the hash table. */ |
This is called for each symbol in the hash table. */ |
2449 |
|
|
2450 |
boolean |
bfd_boolean |
2451 |
_bfd_generic_link_write_global_symbol (h, data) |
_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h, |
2452 |
struct generic_link_hash_entry *h; |
void *data) |
|
PTR data; |
|
2453 |
{ |
{ |
2454 |
struct generic_write_global_symbol_info *wginfo = |
struct generic_write_global_symbol_info *wginfo = data; |
|
(struct generic_write_global_symbol_info *) data; |
|
2455 |
asymbol *sym; |
asymbol *sym; |
2456 |
|
|
2457 |
if (h->root.type == bfd_link_hash_warning) |
if (h->root.type == bfd_link_hash_warning) |
2458 |
h = (struct generic_link_hash_entry *) h->root.u.i.link; |
h = (struct generic_link_hash_entry *) h->root.u.i.link; |
2459 |
|
|
2460 |
if (h->written) |
if (h->written) |
2461 |
return true; |
return TRUE; |
2462 |
|
|
2463 |
h->written = true; |
h->written = TRUE; |
2464 |
|
|
2465 |
if (wginfo->info->strip == strip_all |
if (wginfo->info->strip == strip_all |
2466 |
|| (wginfo->info->strip == strip_some |
|| (wginfo->info->strip == strip_some |
2467 |
&& bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string, |
&& bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string, |
2468 |
false, false) == NULL)) |
FALSE, FALSE) == NULL)) |
2469 |
return true; |
return TRUE; |
2470 |
|
|
2471 |
if (h->sym != (asymbol *) NULL) |
if (h->sym != NULL) |
2472 |
sym = h->sym; |
sym = h->sym; |
2473 |
else |
else |
2474 |
{ |
{ |
2475 |
sym = bfd_make_empty_symbol (wginfo->output_bfd); |
sym = bfd_make_empty_symbol (wginfo->output_bfd); |
2476 |
if (!sym) |
if (!sym) |
2477 |
return false; |
return FALSE; |
2478 |
sym->name = h->root.root.string; |
sym->name = h->root.root.string; |
2479 |
sym->flags = 0; |
sym->flags = 0; |
2480 |
} |
} |
2490 |
abort (); |
abort (); |
2491 |
} |
} |
2492 |
|
|
2493 |
return true; |
return TRUE; |
2494 |
} |
} |
2495 |
|
|
2496 |
/* Create a relocation. */ |
/* Create a relocation. */ |
2497 |
|
|
2498 |
boolean |
bfd_boolean |
2499 |
_bfd_generic_reloc_link_order (abfd, info, sec, link_order) |
_bfd_generic_reloc_link_order (bfd *abfd, |
2500 |
bfd *abfd; |
struct bfd_link_info *info, |
2501 |
struct bfd_link_info *info; |
asection *sec, |
2502 |
asection *sec; |
struct bfd_link_order *link_order) |
|
struct bfd_link_order *link_order; |
|
2503 |
{ |
{ |
2504 |
arelent *r; |
arelent *r; |
2505 |
|
|
2506 |
if (! info->relocateable) |
if (! info->relocatable) |
2507 |
abort (); |
abort (); |
2508 |
if (sec->orelocation == (arelent **) NULL) |
if (sec->orelocation == NULL) |
2509 |
abort (); |
abort (); |
2510 |
|
|
2511 |
r = (arelent *) bfd_alloc (abfd, (bfd_size_type) sizeof (arelent)); |
r = bfd_alloc (abfd, sizeof (arelent)); |
2512 |
if (r == (arelent *) NULL) |
if (r == NULL) |
2513 |
return false; |
return FALSE; |
2514 |
|
|
2515 |
r->address = link_order->offset; |
r->address = link_order->offset; |
2516 |
r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc); |
r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc); |
2517 |
if (r->howto == 0) |
if (r->howto == 0) |
2518 |
{ |
{ |
2519 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2520 |
return false; |
return FALSE; |
2521 |
} |
} |
2522 |
|
|
2523 |
/* Get the symbol to use for the relocation. */ |
/* Get the symbol to use for the relocation. */ |
2530 |
h = ((struct generic_link_hash_entry *) |
h = ((struct generic_link_hash_entry *) |
2531 |
bfd_wrapped_link_hash_lookup (abfd, info, |
bfd_wrapped_link_hash_lookup (abfd, info, |
2532 |
link_order->u.reloc.p->u.name, |
link_order->u.reloc.p->u.name, |
2533 |
false, false, true)); |
FALSE, FALSE, TRUE)); |
2534 |
if (h == (struct generic_link_hash_entry *) NULL |
if (h == NULL |
2535 |
|| ! h->written) |
|| ! h->written) |
2536 |
{ |
{ |
2537 |
if (! ((*info->callbacks->unattached_reloc) |
if (! ((*info->callbacks->unattached_reloc) |
2538 |
(info, link_order->u.reloc.p->u.name, |
(info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) |
2539 |
(bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) |
return FALSE; |
|
return false; |
|
2540 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2541 |
return false; |
return FALSE; |
2542 |
} |
} |
2543 |
r->sym_ptr_ptr = &h->sym; |
r->sym_ptr_ptr = &h->sym; |
2544 |
} |
} |
2552 |
bfd_size_type size; |
bfd_size_type size; |
2553 |
bfd_reloc_status_type rstat; |
bfd_reloc_status_type rstat; |
2554 |
bfd_byte *buf; |
bfd_byte *buf; |
2555 |
boolean ok; |
bfd_boolean ok; |
2556 |
file_ptr loc; |
file_ptr loc; |
2557 |
|
|
2558 |
size = bfd_get_reloc_size (r->howto); |
size = bfd_get_reloc_size (r->howto); |
2559 |
buf = (bfd_byte *) bfd_zmalloc (size); |
buf = bfd_zmalloc (size); |
2560 |
if (buf == (bfd_byte *) NULL) |
if (buf == NULL) |
2561 |
return false; |
return FALSE; |
2562 |
rstat = _bfd_relocate_contents (r->howto, abfd, |
rstat = _bfd_relocate_contents (r->howto, abfd, |
2563 |
(bfd_vma) link_order->u.reloc.p->addend, |
(bfd_vma) link_order->u.reloc.p->addend, |
2564 |
buf); |
buf); |
2571 |
abort (); |
abort (); |
2572 |
case bfd_reloc_overflow: |
case bfd_reloc_overflow: |
2573 |
if (! ((*info->callbacks->reloc_overflow) |
if (! ((*info->callbacks->reloc_overflow) |
2574 |
(info, |
(info, NULL, |
2575 |
(link_order->type == bfd_section_reloc_link_order |
(link_order->type == bfd_section_reloc_link_order |
2576 |
? bfd_section_name (abfd, link_order->u.reloc.p->u.section) |
? bfd_section_name (abfd, link_order->u.reloc.p->u.section) |
2577 |
: link_order->u.reloc.p->u.name), |
: link_order->u.reloc.p->u.name), |
2578 |
r->howto->name, link_order->u.reloc.p->addend, |
r->howto->name, link_order->u.reloc.p->addend, |
2579 |
(bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) |
NULL, NULL, 0))) |
2580 |
{ |
{ |
2581 |
free (buf); |
free (buf); |
2582 |
return false; |
return FALSE; |
2583 |
} |
} |
2584 |
break; |
break; |
2585 |
} |
} |
2586 |
loc = link_order->offset * bfd_octets_per_byte (abfd); |
loc = link_order->offset * bfd_octets_per_byte (abfd); |
2587 |
ok = bfd_set_section_contents (abfd, sec, (PTR) buf, loc, |
ok = bfd_set_section_contents (abfd, sec, buf, loc, size); |
|
(bfd_size_type) size); |
|
2588 |
free (buf); |
free (buf); |
2589 |
if (! ok) |
if (! ok) |
2590 |
return false; |
return FALSE; |
2591 |
|
|
2592 |
r->addend = 0; |
r->addend = 0; |
2593 |
} |
} |
2595 |
sec->orelocation[sec->reloc_count] = r; |
sec->orelocation[sec->reloc_count] = r; |
2596 |
++sec->reloc_count; |
++sec->reloc_count; |
2597 |
|
|
2598 |
return true; |
return TRUE; |
2599 |
} |
} |
2600 |
|
|
2601 |
/* Allocate a new link_order for a section. */ |
/* Allocate a new link_order for a section. */ |
2602 |
|
|
2603 |
struct bfd_link_order * |
struct bfd_link_order * |
2604 |
bfd_new_link_order (abfd, section) |
bfd_new_link_order (bfd *abfd, asection *section) |
|
bfd *abfd; |
|
|
asection *section; |
|
2605 |
{ |
{ |
2606 |
bfd_size_type amt = sizeof (struct bfd_link_order); |
bfd_size_type amt = sizeof (struct bfd_link_order); |
2607 |
struct bfd_link_order *new; |
struct bfd_link_order *new; |
2608 |
|
|
2609 |
new = (struct bfd_link_order *) bfd_zalloc (abfd, amt); |
new = bfd_zalloc (abfd, amt); |
2610 |
if (!new) |
if (!new) |
2611 |
return NULL; |
return NULL; |
2612 |
|
|
2613 |
new->type = bfd_undefined_link_order; |
new->type = bfd_undefined_link_order; |
2614 |
|
|
2615 |
if (section->link_order_tail != (struct bfd_link_order *) NULL) |
if (section->link_order_tail != NULL) |
2616 |
section->link_order_tail->next = new; |
section->link_order_tail->next = new; |
2617 |
else |
else |
2618 |
section->link_order_head = new; |
section->link_order_head = new; |
2625 |
the reloc_link_order types here, since they depend upon the details |
the reloc_link_order types here, since they depend upon the details |
2626 |
of how the particular backends generates relocs. */ |
of how the particular backends generates relocs. */ |
2627 |
|
|
2628 |
boolean |
bfd_boolean |
2629 |
_bfd_default_link_order (abfd, info, sec, link_order) |
_bfd_default_link_order (bfd *abfd, |
2630 |
bfd *abfd; |
struct bfd_link_info *info, |
2631 |
struct bfd_link_info *info; |
asection *sec, |
2632 |
asection *sec; |
struct bfd_link_order *link_order) |
|
struct bfd_link_order *link_order; |
|
2633 |
{ |
{ |
2634 |
switch (link_order->type) |
switch (link_order->type) |
2635 |
{ |
{ |
2640 |
abort (); |
abort (); |
2641 |
case bfd_indirect_link_order: |
case bfd_indirect_link_order: |
2642 |
return default_indirect_link_order (abfd, info, sec, link_order, |
return default_indirect_link_order (abfd, info, sec, link_order, |
2643 |
false); |
FALSE); |
2644 |
case bfd_data_link_order: |
case bfd_data_link_order: |
2645 |
return default_data_link_order (abfd, info, sec, link_order); |
return default_data_link_order (abfd, info, sec, link_order); |
2646 |
} |
} |
2648 |
|
|
2649 |
/* Default routine to handle a bfd_data_link_order. */ |
/* Default routine to handle a bfd_data_link_order. */ |
2650 |
|
|
2651 |
static boolean |
static bfd_boolean |
2652 |
default_data_link_order (abfd, info, sec, link_order) |
default_data_link_order (bfd *abfd, |
2653 |
bfd *abfd; |
struct bfd_link_info *info ATTRIBUTE_UNUSED, |
2654 |
struct bfd_link_info *info ATTRIBUTE_UNUSED; |
asection *sec, |
2655 |
asection *sec; |
struct bfd_link_order *link_order) |
|
struct bfd_link_order *link_order; |
|
2656 |
{ |
{ |
2657 |
bfd_size_type size; |
bfd_size_type size; |
2658 |
size_t fill_size; |
size_t fill_size; |
2659 |
bfd_byte *fill; |
bfd_byte *fill; |
2660 |
file_ptr loc; |
file_ptr loc; |
2661 |
boolean result; |
bfd_boolean result; |
2662 |
|
|
2663 |
BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); |
BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); |
2664 |
|
|
2665 |
size = link_order->size; |
size = link_order->size; |
2666 |
if (size == 0) |
if (size == 0) |
2667 |
return true; |
return TRUE; |
2668 |
|
|
2669 |
fill = link_order->u.data.contents; |
fill = link_order->u.data.contents; |
2670 |
fill_size = link_order->u.data.size; |
fill_size = link_order->u.data.size; |
2671 |
if (fill_size != 0 && fill_size < size) |
if (fill_size != 0 && fill_size < size) |
2672 |
{ |
{ |
2673 |
bfd_byte *p; |
bfd_byte *p; |
2674 |
fill = (bfd_byte *) bfd_malloc (size); |
fill = bfd_malloc (size); |
2675 |
if (fill == NULL) |
if (fill == NULL) |
2676 |
return false; |
return FALSE; |
2677 |
p = fill; |
p = fill; |
2678 |
if (fill_size == 1) |
if (fill_size == 1) |
2679 |
memset (p, (int) link_order->u.data.contents[0], (size_t) size); |
memset (p, (int) link_order->u.data.contents[0], (size_t) size); |
2702 |
|
|
2703 |
/* Default routine to handle a bfd_indirect_link_order. */ |
/* Default routine to handle a bfd_indirect_link_order. */ |
2704 |
|
|
2705 |
static boolean |
static bfd_boolean |
2706 |
default_indirect_link_order (output_bfd, info, output_section, link_order, |
default_indirect_link_order (bfd *output_bfd, |
2707 |
generic_linker) |
struct bfd_link_info *info, |
2708 |
bfd *output_bfd; |
asection *output_section, |
2709 |
struct bfd_link_info *info; |
struct bfd_link_order *link_order, |
2710 |
asection *output_section; |
bfd_boolean generic_linker) |
|
struct bfd_link_order *link_order; |
|
|
boolean generic_linker; |
|
2711 |
{ |
{ |
2712 |
asection *input_section; |
asection *input_section; |
2713 |
bfd *input_bfd; |
bfd *input_bfd; |
2719 |
BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); |
BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); |
2720 |
|
|
2721 |
if (link_order->size == 0) |
if (link_order->size == 0) |
2722 |
return true; |
return TRUE; |
2723 |
|
|
2724 |
input_section = link_order->u.indirect.section; |
input_section = link_order->u.indirect.section; |
2725 |
input_bfd = input_section->owner; |
input_bfd = input_section->owner; |
2726 |
|
|
2727 |
BFD_ASSERT (input_section->output_section == output_section); |
BFD_ASSERT (input_section->output_section == output_section); |
2728 |
BFD_ASSERT (input_section->output_offset == link_order->offset); |
BFD_ASSERT (input_section->output_offset == link_order->offset); |
2729 |
BFD_ASSERT (input_section->_cooked_size == link_order->size); |
BFD_ASSERT (input_section->size == link_order->size); |
2730 |
|
|
2731 |
if (info->relocateable |
if (info->relocatable |
2732 |
&& input_section->reloc_count > 0 |
&& input_section->reloc_count > 0 |
2733 |
&& output_section->orelocation == (arelent **) NULL) |
&& output_section->orelocation == NULL) |
2734 |
{ |
{ |
2735 |
/* Space has not been allocated for the output relocations. |
/* Space has not been allocated for the output relocations. |
2736 |
This can happen when we are called by a specific backend |
This can happen when we are called by a specific backend |
2738 |
types of object files. Handling this case correctly is |
types of object files. Handling this case correctly is |
2739 |
difficult, and sometimes impossible. */ |
difficult, and sometimes impossible. */ |
2740 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
2741 |
(_("Attempt to do relocateable link with %s input and %s output"), |
(_("Attempt to do relocatable link with %s input and %s output"), |
2742 |
bfd_get_target (input_bfd), bfd_get_target (output_bfd)); |
bfd_get_target (input_bfd), bfd_get_target (output_bfd)); |
2743 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
2744 |
return false; |
return FALSE; |
2745 |
} |
} |
2746 |
|
|
2747 |
if (! generic_linker) |
if (! generic_linker) |
2754 |
a specific linker, presumably because we are linking |
a specific linker, presumably because we are linking |
2755 |
different types of object files together. */ |
different types of object files together. */ |
2756 |
if (! generic_link_read_symbols (input_bfd)) |
if (! generic_link_read_symbols (input_bfd)) |
2757 |
return false; |
return FALSE; |
2758 |
|
|
2759 |
/* Since we have been called by a specific linker, rather than |
/* Since we have been called by a specific linker, rather than |
2760 |
the generic linker, the values of the symbols will not be |
the generic linker, the values of the symbols will not be |
2782 |
/* sym->udata may have been set by |
/* sym->udata may have been set by |
2783 |
generic_link_add_symbol_list. */ |
generic_link_add_symbol_list. */ |
2784 |
if (sym->udata.p != NULL) |
if (sym->udata.p != NULL) |
2785 |
h = (struct bfd_link_hash_entry *) sym->udata.p; |
h = sym->udata.p; |
2786 |
else if (bfd_is_und_section (bfd_get_section (sym))) |
else if (bfd_is_und_section (bfd_get_section (sym))) |
2787 |
h = bfd_wrapped_link_hash_lookup (output_bfd, info, |
h = bfd_wrapped_link_hash_lookup (output_bfd, info, |
2788 |
bfd_asymbol_name (sym), |
bfd_asymbol_name (sym), |
2789 |
false, false, true); |
FALSE, FALSE, TRUE); |
2790 |
else |
else |
2791 |
h = bfd_link_hash_lookup (info->hash, |
h = bfd_link_hash_lookup (info->hash, |
2792 |
bfd_asymbol_name (sym), |
bfd_asymbol_name (sym), |
2793 |
false, false, true); |
FALSE, FALSE, TRUE); |
2794 |
if (h != NULL) |
if (h != NULL) |
2795 |
set_symbol_from_hash (sym, h); |
set_symbol_from_hash (sym, h); |
2796 |
} |
} |
2798 |
} |
} |
2799 |
|
|
2800 |
/* Get and relocate the section contents. */ |
/* Get and relocate the section contents. */ |
2801 |
sec_size = bfd_section_size (input_bfd, input_section); |
sec_size = (input_section->rawsize > input_section->size |
2802 |
contents = ((bfd_byte *) bfd_malloc (sec_size)); |
? input_section->rawsize |
2803 |
|
: input_section->size); |
2804 |
|
contents = bfd_malloc (sec_size); |
2805 |
if (contents == NULL && sec_size != 0) |
if (contents == NULL && sec_size != 0) |
2806 |
goto error_return; |
goto error_return; |
2807 |
new_contents = (bfd_get_relocated_section_contents |
new_contents = (bfd_get_relocated_section_contents |
2808 |
(output_bfd, info, link_order, contents, info->relocateable, |
(output_bfd, info, link_order, contents, info->relocatable, |
2809 |
_bfd_generic_link_get_symbols (input_bfd))); |
_bfd_generic_link_get_symbols (input_bfd))); |
2810 |
if (!new_contents) |
if (!new_contents) |
2811 |
goto error_return; |
goto error_return; |
2813 |
/* Output the section contents. */ |
/* Output the section contents. */ |
2814 |
loc = link_order->offset * bfd_octets_per_byte (output_bfd); |
loc = link_order->offset * bfd_octets_per_byte (output_bfd); |
2815 |
if (! bfd_set_section_contents (output_bfd, output_section, |
if (! bfd_set_section_contents (output_bfd, output_section, |
2816 |
(PTR) new_contents, loc, link_order->size)) |
new_contents, loc, link_order->size)) |
2817 |
goto error_return; |
goto error_return; |
2818 |
|
|
2819 |
if (contents != NULL) |
if (contents != NULL) |
2820 |
free (contents); |
free (contents); |
2821 |
return true; |
return TRUE; |
2822 |
|
|
2823 |
error_return: |
error_return: |
2824 |
if (contents != NULL) |
if (contents != NULL) |
2825 |
free (contents); |
free (contents); |
2826 |
return false; |
return FALSE; |
2827 |
} |
} |
2828 |
|
|
2829 |
/* A little routine to count the number of relocs in a link_order |
/* A little routine to count the number of relocs in a link_order |
2830 |
list. */ |
list. */ |
2831 |
|
|
2832 |
unsigned int |
unsigned int |
2833 |
_bfd_count_link_order_relocs (link_order) |
_bfd_count_link_order_relocs (struct bfd_link_order *link_order) |
|
struct bfd_link_order *link_order; |
|
2834 |
{ |
{ |
2835 |
register unsigned int c; |
register unsigned int c; |
2836 |
register struct bfd_link_order *l; |
register struct bfd_link_order *l; |
2837 |
|
|
2838 |
c = 0; |
c = 0; |
2839 |
for (l = link_order; l != (struct bfd_link_order *) NULL; l = l->next) |
for (l = link_order; l != NULL; l = l->next) |
2840 |
{ |
{ |
2841 |
if (l->type == bfd_section_reloc_link_order |
if (l->type == bfd_section_reloc_link_order |
2842 |
|| l->type == bfd_symbol_reloc_link_order) |
|| l->type == bfd_symbol_reloc_link_order) |
2851 |
bfd_link_split_section |
bfd_link_split_section |
2852 |
|
|
2853 |
SYNOPSIS |
SYNOPSIS |
2854 |
boolean bfd_link_split_section(bfd *abfd, asection *sec); |
bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); |
2855 |
|
|
2856 |
DESCRIPTION |
DESCRIPTION |
2857 |
Return nonzero if @var{sec} should be split during a |
Return nonzero if @var{sec} should be split during a |
2863 |
|
|
2864 |
*/ |
*/ |
2865 |
|
|
2866 |
boolean |
bfd_boolean |
2867 |
_bfd_generic_link_split_section (abfd, sec) |
_bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, |
2868 |
bfd *abfd ATTRIBUTE_UNUSED; |
asection *sec ATTRIBUTE_UNUSED) |
2869 |
asection *sec ATTRIBUTE_UNUSED; |
{ |
2870 |
|
return FALSE; |
2871 |
|
} |
2872 |
|
|
2873 |
|
/* |
2874 |
|
FUNCTION |
2875 |
|
bfd_section_already_linked |
2876 |
|
|
2877 |
|
SYNOPSIS |
2878 |
|
void bfd_section_already_linked (bfd *abfd, asection *sec); |
2879 |
|
|
2880 |
|
DESCRIPTION |
2881 |
|
Check if @var{sec} has been already linked during a reloceatable |
2882 |
|
or final link. |
2883 |
|
|
2884 |
|
.#define bfd_section_already_linked(abfd, sec) \ |
2885 |
|
. BFD_SEND (abfd, _section_already_linked, (abfd, sec)) |
2886 |
|
. |
2887 |
|
|
2888 |
|
*/ |
2889 |
|
|
2890 |
|
/* Sections marked with the SEC_LINK_ONCE flag should only be linked |
2891 |
|
once into the output. This routine checks each section, and |
2892 |
|
arrange to discard it if a section of the same name has already |
2893 |
|
been linked. This code assumes that all relevant sections have the |
2894 |
|
SEC_LINK_ONCE flag set; that is, it does not depend solely upon the |
2895 |
|
section name. bfd_section_already_linked is called via |
2896 |
|
bfd_map_over_sections. */ |
2897 |
|
|
2898 |
|
/* The hash table. */ |
2899 |
|
|
2900 |
|
static struct bfd_hash_table _bfd_section_already_linked_table; |
2901 |
|
|
2902 |
|
/* Support routines for the hash table used by section_already_linked, |
2903 |
|
initialize the table, traverse, lookup, fill in an entry and remove |
2904 |
|
the table. */ |
2905 |
|
|
2906 |
|
void |
2907 |
|
bfd_section_already_linked_table_traverse |
2908 |
|
(bfd_boolean (*func) (struct bfd_section_already_linked_hash_entry *, |
2909 |
|
void *), void *info) |
2910 |
|
{ |
2911 |
|
bfd_hash_traverse (&_bfd_section_already_linked_table, |
2912 |
|
(bfd_boolean (*) (struct bfd_hash_entry *, |
2913 |
|
void *)) func, |
2914 |
|
info); |
2915 |
|
} |
2916 |
|
|
2917 |
|
struct bfd_section_already_linked_hash_entry * |
2918 |
|
bfd_section_already_linked_table_lookup (const char *name) |
2919 |
|
{ |
2920 |
|
return ((struct bfd_section_already_linked_hash_entry *) |
2921 |
|
bfd_hash_lookup (&_bfd_section_already_linked_table, name, |
2922 |
|
TRUE, FALSE)); |
2923 |
|
} |
2924 |
|
|
2925 |
|
void |
2926 |
|
bfd_section_already_linked_table_insert |
2927 |
|
(struct bfd_section_already_linked_hash_entry *already_linked_list, |
2928 |
|
asection *sec) |
2929 |
|
{ |
2930 |
|
struct bfd_section_already_linked *l; |
2931 |
|
|
2932 |
|
/* Allocate the memory from the same obstack as the hash table is |
2933 |
|
kept in. */ |
2934 |
|
l = bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l); |
2935 |
|
l->sec = sec; |
2936 |
|
l->next = already_linked_list->entry; |
2937 |
|
already_linked_list->entry = l; |
2938 |
|
} |
2939 |
|
|
2940 |
|
static struct bfd_hash_entry * |
2941 |
|
already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED, |
2942 |
|
struct bfd_hash_table *table, |
2943 |
|
const char *string ATTRIBUTE_UNUSED) |
2944 |
{ |
{ |
2945 |
return false; |
struct bfd_section_already_linked_hash_entry *ret = |
2946 |
|
bfd_hash_allocate (table, sizeof *ret); |
2947 |
|
|
2948 |
|
ret->entry = NULL; |
2949 |
|
|
2950 |
|
return &ret->root; |
2951 |
|
} |
2952 |
|
|
2953 |
|
bfd_boolean |
2954 |
|
bfd_section_already_linked_table_init (void) |
2955 |
|
{ |
2956 |
|
return bfd_hash_table_init_n (&_bfd_section_already_linked_table, |
2957 |
|
already_linked_newfunc, 42); |
2958 |
|
} |
2959 |
|
|
2960 |
|
void |
2961 |
|
bfd_section_already_linked_table_free (void) |
2962 |
|
{ |
2963 |
|
bfd_hash_table_free (&_bfd_section_already_linked_table); |
2964 |
|
} |
2965 |
|
|
2966 |
|
/* This is used on non-ELF inputs. */ |
2967 |
|
|
2968 |
|
void |
2969 |
|
_bfd_generic_section_already_linked (bfd *abfd, asection *sec) |
2970 |
|
{ |
2971 |
|
flagword flags; |
2972 |
|
const char *name; |
2973 |
|
struct bfd_section_already_linked *l; |
2974 |
|
struct bfd_section_already_linked_hash_entry *already_linked_list; |
2975 |
|
|
2976 |
|
flags = sec->flags; |
2977 |
|
if ((flags & SEC_LINK_ONCE) == 0) |
2978 |
|
return; |
2979 |
|
|
2980 |
|
/* FIXME: When doing a relocatable link, we may have trouble |
2981 |
|
copying relocations in other sections that refer to local symbols |
2982 |
|
in the section being discarded. Those relocations will have to |
2983 |
|
be converted somehow; as of this writing I'm not sure that any of |
2984 |
|
the backends handle that correctly. |
2985 |
|
|
2986 |
|
It is tempting to instead not discard link once sections when |
2987 |
|
doing a relocatable link (technically, they should be discarded |
2988 |
|
whenever we are building constructors). However, that fails, |
2989 |
|
because the linker winds up combining all the link once sections |
2990 |
|
into a single large link once section, which defeats the purpose |
2991 |
|
of having link once sections in the first place. */ |
2992 |
|
|
2993 |
|
name = bfd_get_section_name (abfd, sec); |
2994 |
|
|
2995 |
|
already_linked_list = bfd_section_already_linked_table_lookup (name); |
2996 |
|
|
2997 |
|
for (l = already_linked_list->entry; l != NULL; l = l->next) |
2998 |
|
{ |
2999 |
|
bfd_boolean skip = FALSE; |
3000 |
|
struct coff_comdat_info *s_comdat |
3001 |
|
= bfd_coff_get_comdat_section (abfd, sec); |
3002 |
|
struct coff_comdat_info *l_comdat |
3003 |
|
= bfd_coff_get_comdat_section (l->sec->owner, l->sec); |
3004 |
|
|
3005 |
|
/* We may have 3 different sections on the list: group section, |
3006 |
|
comdat section and linkonce section. SEC may be a linkonce or |
3007 |
|
comdat section. We always ignore group section. For non-COFF |
3008 |
|
inputs, we also ignore comdat section. |
3009 |
|
|
3010 |
|
FIXME: Is that safe to match a linkonce section with a comdat |
3011 |
|
section for COFF inputs? */ |
3012 |
|
if ((l->sec->flags & SEC_GROUP) != 0) |
3013 |
|
skip = TRUE; |
3014 |
|
else if (bfd_get_flavour (abfd) == bfd_target_coff_flavour) |
3015 |
|
{ |
3016 |
|
if (s_comdat != NULL |
3017 |
|
&& l_comdat != NULL |
3018 |
|
&& strcmp (s_comdat->name, l_comdat->name) != 0) |
3019 |
|
skip = TRUE; |
3020 |
|
} |
3021 |
|
else if (l_comdat != NULL) |
3022 |
|
skip = TRUE; |
3023 |
|
|
3024 |
|
if (!skip) |
3025 |
|
{ |
3026 |
|
/* The section has already been linked. See if we should |
3027 |
|
issue a warning. */ |
3028 |
|
switch (flags & SEC_LINK_DUPLICATES) |
3029 |
|
{ |
3030 |
|
default: |
3031 |
|
abort (); |
3032 |
|
|
3033 |
|
case SEC_LINK_DUPLICATES_DISCARD: |
3034 |
|
break; |
3035 |
|
|
3036 |
|
case SEC_LINK_DUPLICATES_ONE_ONLY: |
3037 |
|
(*_bfd_error_handler) |
3038 |
|
(_("%B: warning: ignoring duplicate section `%A'\n"), |
3039 |
|
abfd, sec); |
3040 |
|
break; |
3041 |
|
|
3042 |
|
case SEC_LINK_DUPLICATES_SAME_CONTENTS: |
3043 |
|
/* FIXME: We should really dig out the contents of both |
3044 |
|
sections and memcmp them. The COFF/PE spec says that |
3045 |
|
the Microsoft linker does not implement this |
3046 |
|
correctly, so I'm not going to bother doing it |
3047 |
|
either. */ |
3048 |
|
/* Fall through. */ |
3049 |
|
case SEC_LINK_DUPLICATES_SAME_SIZE: |
3050 |
|
if (sec->size != l->sec->size) |
3051 |
|
(*_bfd_error_handler) |
3052 |
|
(_("%B: warning: duplicate section `%A' has different size\n"), |
3053 |
|
abfd, sec); |
3054 |
|
break; |
3055 |
|
} |
3056 |
|
|
3057 |
|
/* Set the output_section field so that lang_add_section |
3058 |
|
does not create a lang_input_section structure for this |
3059 |
|
section. Since there might be a symbol in the section |
3060 |
|
being discarded, we must retain a pointer to the section |
3061 |
|
which we are really going to use. */ |
3062 |
|
sec->output_section = bfd_abs_section_ptr; |
3063 |
|
sec->kept_section = l->sec; |
3064 |
|
|
3065 |
|
return; |
3066 |
|
} |
3067 |
|
} |
3068 |
|
|
3069 |
|
/* This is the first section with this name. Record it. */ |
3070 |
|
bfd_section_already_linked_table_insert (already_linked_list, sec); |
3071 |
} |
} |